diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/Contact.php | 3 | ||||
-rw-r--r-- | include/ConversationObject.php | 6 | ||||
-rw-r--r-- | include/bbcode.php | 28 | ||||
-rw-r--r-- | include/comanche.php | 9 | ||||
-rw-r--r-- | include/config.php | 9 | ||||
-rw-r--r-- | include/contact_widgets.php | 2 | ||||
-rw-r--r-- | include/dir_fns.php | 64 | ||||
-rw-r--r-- | include/enotify.php | 7 | ||||
-rw-r--r-- | include/features.php | 1 | ||||
-rw-r--r-- | include/identity.php | 2 | ||||
-rwxr-xr-x | include/items.php | 253 | ||||
-rw-r--r-- | include/onedirsync.php | 42 | ||||
-rw-r--r-- | include/page_widgets.php | 2 | ||||
-rw-r--r-- | include/permissions.php | 1 | ||||
-rw-r--r-- | include/poller.php | 128 | ||||
-rw-r--r-- | include/security.php | 49 | ||||
-rwxr-xr-x | include/text.php | 23 | ||||
-rw-r--r-- | include/zot.php | 57 |
18 files changed, 502 insertions, 184 deletions
diff --git a/include/Contact.php b/include/Contact.php index b9e879bcf..46c84aab6 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -219,7 +219,8 @@ function channel_remove($channel_id, $local = true) { $r = q("update channel set channel_pageflags = (channel_pageflags | %d), channel_r_stream = 0, channel_r_profile = 0, channel_r_photos = 0, channel_r_abook = 0, channel_w_stream = 0, channel_w_wall = 0, channel_w_tagwall = 0, channel_w_comment = 0, channel_w_mail = 0, channel_w_photos = 0, channel_w_chat = 0, channel_a_delegate = 0, - channel_r_storage = 0, channel_w_storage = 0, channel_r_pages = 0, channel_w_pages = 0 where channel_id = %d limit 1", + channel_r_storage = 0, channel_w_storage = 0, channel_r_pages = 0, channel_w_pages = 0, channel_a_republish = 0 + where channel_id = %d limit 1", intval(PAGE_REMOVED), intval($channel_id) ); diff --git a/include/ConversationObject.php b/include/ConversationObject.php index 5157dad05..bb144d893 100644 --- a/include/ConversationObject.php +++ b/include/ConversationObject.php @@ -7,6 +7,7 @@ require_once('boot.php'); require_once('include/BaseObject.php'); require_once('include/ItemObject.php'); require_once('include/text.php'); +require_once('include/items.php'); /** * A list of threads @@ -154,7 +155,10 @@ class Conversation extends BaseObject { $item->set_commentable(false); } elseif(($this->observer) && (! $item->is_commentable())) { - $item->set_commentable(can_comment_on_post($this->observer['xchan_hash'],$item->data)); + if((array_key_exists('owner',$item->data)) && ($item->data['owner']['abook_flags'] & ABOOK_FLAG_SELF)) + $item->set_commentable(perm_is_allowed($this->profile_owner,$this->observer['xchan_hash'],'post_comments')); + else + $item->set_commentable(can_comment_on_post($this->observer['xchan_hash'],$item->data)); } $item->set_conversation($this); diff --git a/include/bbcode.php b/include/bbcode.php index 997cbac2e..9b9c954c1 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -217,6 +217,18 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) { $ev = bbtoevent($Text); + // process [observer] tags before we do anything else because we might + // be stripping away stuff that then doesn't need to be worked on anymore + $observer = $a->get_observer(); + if (strpos($Text,'[/observer]') !== false) { + if ($observer) { + $Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text); + $Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text); + } else { + $Text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $Text); + $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text); + } + } // Replace any html brackets with HTML Entities to prevent executing HTML or script // Don't use strip_tags here because it breaks [url] search by replacing & with amp @@ -246,6 +258,22 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) { // Set up the parameters for a MAIL search string $MAILSearchString = $URLSearchString; + // replace [observer.baseurl] + if ($observer) { + $obsBaseURL = $observer['xchan_url']; + $obsBaseURL = preg_replace("/\/channel\/.*$/", '', $obsBaseURL); + $Text = str_replace('[observer.baseurl]', $obsBaseURL, $Text); + $Text = str_replace('[observer.url]',$observer['xchan_url'], $Text); + $Text = str_replace('[observer.name]',$observer['xchan_name'], $Text); + $Text = str_replace('[observer.address]',$observer['xchan_addr'], $Text); + $Text = str_replace('[observer.photo]','[zmg]'.$observer['xchan_photo_l'].'[/zmg]', $Text); + } else { + $Text = str_replace('[observer.baseurl]', '', $Text); + $Text = str_replace('[observer.url]','', $Text); + $Text = str_replace('[observer.name]','', $Text); + $Text = str_replace('[observer.address]','', $Text); + $Text = str_replace('[observer.photo]','', $Text); + } // Perform URL Search diff --git a/include/comanche.php b/include/comanche.php index eb0de96c7..f1dd0e521 100644 --- a/include/comanche.php +++ b/include/comanche.php @@ -1,7 +1,7 @@ <?php /** @file */ require_once('include/security.php'); - +require_once('include/menu.php'); // When editing a webpage - a dropdown is needed to select a page layout // On submit, the pdl_select value (which is the mid of an item with item_restrict = ITEM_PDL) is stored in // the webpage's resource_id, with resource_type 'pdl'. @@ -74,7 +74,7 @@ function comanche_parser(&$a,$s) { function comanche_menu($name) { $a = get_app(); $m = menu_fetch($name,$a->profile['profile_uid'],get_observer_hash()); - return render_menu($m); + return menu_render($m); } function comanche_replace_region($match) { @@ -85,9 +85,10 @@ function comanche_replace_region($match) { } function comanche_block($name) { + $o = ''; - $r = q("select * from item left join item_id on iid = item_id and item_id.uid = item.uid and item.uid = %d and service = 'BUILDBLOCK' and sid = '%s' limit 1", - intval($a->profile['profile_uid']), + $r = q("select * from item inner join item_id on iid = item.id and item_id.uid = item.uid and item.uid = %d and service = 'BUILDBLOCK' and sid = '%s' limit 1", + intval(get_app()->profile['profile_uid']), dbesc($name) ); if($r) { diff --git a/include/config.php b/include/config.php index 38840f5e4..ccd907424 100644 --- a/include/config.php +++ b/include/config.php @@ -24,6 +24,15 @@ function load_config($family) { if(! array_key_exists('config_loaded',$a->config[$family])) { $r = q("SELECT * FROM config WHERE cat = '%s'", dbesc($family)); + + // This is often one of the earliest database calls in the life of the page. + // If the DB was successfully opened, but we can't read from it, + // we must assume catastrophic failure of the DB. Report the system down. + + if($r === false) { + system_unavailable(); + } + if($r !== false) { if($r) { foreach($r as $rr) { diff --git a/include/contact_widgets.php b/include/contact_widgets.php index bc7faebc3..af05f8c9f 100644 --- a/include/contact_widgets.php +++ b/include/contact_widgets.php @@ -47,7 +47,7 @@ function findpeople_widget() { '$hint' => t('Examples: Robert Morgenstein, Fishing'), '$findthem' => t('Find'), '$suggest' => t('Channel Suggestions'), - '$similar' => t('Similar Interests'), + '$similar' => '', // FIXME and uncomment when mod/match working // t('Similar Interests'), '$random' => t('Random Profile'), '$inv' => t('Invite Friends') )); diff --git a/include/dir_fns.php b/include/dir_fns.php index 0b678fd91..585121434 100644 --- a/include/dir_fns.php +++ b/include/dir_fns.php @@ -13,7 +13,7 @@ function sync_directories($dirmode) { return; $r = q("select * from site where (site_flags & %d) and site_url != '%s'", - intval(DIRECTORY_MODE_PRIMARY), + intval(DIRECTORY_MODE_PRIMARY|DIRECTORY_MODE_SECONDARY), dbesc(z_root()) ); @@ -34,21 +34,79 @@ function sync_directories($dirmode) { dbesc($r[0]['site_directory']) ); + $r = q("select * from site where (site_flags & %d) and site_url != '%s'", + intval(DIRECTORY_MODE_PRIMARY|DIRECTORY_MODE_SECONDARY), + dbesc(z_root()) + ); + } + if(! $r) + return; + foreach($r as $rr) { + if(! $rr['site_directory']) + continue; + $x = z_fetch_url($rr['site_directory'] . '?f=&sync=' . urlencode($rr['site_sync'])); + if(! $x['success']) + continue; + $j = json_decode($x['body'],true); + if((! $j['transactions']) || (! is_array($j['transactions']))) + continue; + + q("update site set site_sync = '%s' where site_url = '%s' limit 1", + dbesc(datetime_convert()), + dbesc($rr['site_url']) + ); + logger('sync_directories: ' . $rr['site_url'] . ': ' . print_r($j,true), LOGGER_DATA); + + if(count($j['transactions'])) { + foreach($j['transactions'] as $t) { + $r = q("select * from updates where ud_guid = '%s' limit 1", + dbesc($t['transaction_id']) + ); + if($r) + continue; + $ud_flags = 0; + if(is_array($t['flags']) && in_array('deleted',$t['flags'])) + $ud_flags |= UPDATE_FLAGS_DELETED; + $z = q("insert into updates ( ud_hash, ud_guid, ud_date, ud_flags, ud_addr ) + values ( '%s', '%s', '%s', '%d, '%s' ) ", + dbesc($t['hash']), + dbesc($t['transaction_id']), + dbesc($t['timestamp']), + intval($ud_flags), + dbesc($t['address']) + ); + } + } + } +} +function update_directory_entry($ud) { + logger('update_directory_entry: ' . print_r($ud,true), LOGGER_DATA); + if($ud['ud_addr'] && (! ($ud['ud_flags'] & UPDATE_FLAGS_DELETED))) { + $x = zot_finger($ud['ud_addr'],''); + if($x['success']) { + $j = json_decode($x['body'],true); + $y = import_xchan($j,0); + } + else { + $r = q("update updates set ud_last = '%s' where ud_addr = '%s'", + dbesc(datetime_convert()), + dbesc($ud['ud_addr']) + ); + } + } } - - function syncdirs($uid) { logger('syncdirs', LOGGER_DEBUG); diff --git a/include/enotify.php b/include/enotify.php index b2a4f5856..147023f41 100644 --- a/include/enotify.php +++ b/include/enotify.php @@ -51,9 +51,9 @@ function notification($params) { $additional_mail_header = ""; if(array_key_exists('item',$params)) { + require_once('include/conversation.php'); // if it's a normal item... if(array_key_exists('verb',$params['item'])) { - require_once('include/conversation.php'); // localize_item() alters the original item so make a copy first $i = $params['item']; logger('calling localize'); @@ -89,6 +89,11 @@ function notification($params) { if($params['type'] == NOTIFY_COMMENT) { // logger("notification: params = " . print_r($params, true), LOGGER_DEBUG); + // ignore like/unlike activity on posts - they probably require a sepearate notification preference + + if(array_key_exists('item',$params) && (! visible_activity($params['item']))) + return; + $parent_id = $params['parent']; // Check to see if there was already a notify for this post. diff --git a/include/features.php b/include/features.php index 6272b33ea..9950039c0 100644 --- a/include/features.php +++ b/include/features.php @@ -35,6 +35,7 @@ function get_features() { t('Post Composition Features'), array('richtext', t('Richtext Editor'), t('Enable richtext editor')), array('preview', t('Post Preview'), t('Allow previewing posts and comments before publishing them')), + array('channel_sources', t('Channel Sources'), t('Automatically import channel content from other channels or feeds')), ), // Network Tools diff --git a/include/identity.php b/include/identity.php index 98209c8ae..d6b6735f6 100644 --- a/include/identity.php +++ b/include/identity.php @@ -48,7 +48,7 @@ function validate_channelname($name) { function create_dir_account() { - create_account(array( + create_identity(array( 'account_id' => 'xxx', // This will create an identity with an (integer) account_id of 0, but account_id is required 'nickname' => 'dir', 'name' => 'Directory', diff --git a/include/items.php b/include/items.php index 44917233f..18736f974 100755 --- a/include/items.php +++ b/include/items.php @@ -24,10 +24,31 @@ function collect_recipients($item,&$private) { if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid']) { $allow_people = expand_acl($item['allow_cid']); $allow_groups = expand_groups(expand_acl($item['allow_gid'])); + + $recipients = array_unique(array_merge($allow_people,$allow_groups)); + + // if you specifically deny somebody but haven't allowed anybody, we'll allow everybody in your + // address book minus the denied connections. The post is still private and can't be seen publicly + // as that would allow the denied person to see the post by logging out. + + if((! $item['allow_cid']) && (! $item['allow_gid'])) { + $r = q("select * from abook where abook_channel = %d and not (abook_flags & %d) and not (abook_flags & %d) and not (abook_flags & %d)", + intval($item['uid']), + intval(ABOOK_FLAG_SELF), + intval(ABOOK_FLAG_PENDING), + intval(ABOOK_FLAG_ARCHIVED) + ); + + if($r) { + foreach($r as $rr) { + $recipients[] = $rr['abook_xchan']; + } + } + } + $deny_people = expand_acl($item['deny_cid']); $deny_groups = expand_groups(expand_acl($item['deny_gid'])); - $recipients = array_unique(array_merge($allow_people,$allow_groups)); $deny = array_unique(array_merge($deny_people,$deny_groups)); $recipients = array_diff($recipients,$deny); $private = true; @@ -62,9 +83,20 @@ function collect_recipients($item,&$private) { } +/** + * @function can_comment_on_post($observer_xchan,$item); + * + * This function examines the comment_policy attached to an item and decides if the current observer has + * sufficient privileges to comment. This will normally be called on a remote site where perm_is_allowed() + * will not be suitable because the post owner does not have a local channel_id. + * Generally we should look at the item - in particular the author['book_flags'] and see if ABOOK_FLAG_SELF is set. + * If it is, you should be able to use perm_is_allowed( ... 'post_comments'), and if it isn't you need to call + * can_comment_on_post() + */ +function can_comment_on_post($observer_xchan,$item) { +// logger('can_comment_on_post: comment_policy: ' . $item['comment_policy'], LOGGER_DEBUG); -function can_comment_on_post($observer_xchan,$item) { if(! $observer_xchan) return false; if($item['comment_policy'] === 'none') @@ -77,6 +109,10 @@ function can_comment_on_post($observer_xchan,$item) { return true; break; case 'public': + // We don't allow public comments yet, until a policy + // for dealing with anonymous comments is in place with + // a means to moderate comments. Until that time, return + // false. return false; break; case 'contacts': @@ -1265,14 +1301,9 @@ function get_atom_elements($feed,$item) { $res['object'] .= '<orig>' . xmlify($body) . '</orig>' . "\n"; if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) { - $body = html2bb_video($body); - - $config = HTMLPurifier_Config::createDefault(); - $config->set('Cache.DefinitionImpl', null); - - $purifier = new HTMLPurifier($config); - $body = $purifier->purify($body); + $body = purify_html($body); $body = html2bbcode($body); + } $res['object'] .= '<content>' . $body . '</content>' . "\n"; @@ -1303,13 +1334,7 @@ function get_atom_elements($feed,$item) { $res['target'] .= '<orig>' . xmlify($body) . '</orig>' . "\n"; if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) { - $body = html2bb_video($body); - - $config = HTMLPurifier_Config::createDefault(); - $config->set('Cache.DefinitionImpl', null); - - $purifier = new HTMLPurifier($config); - $body = $purifier->purify($body); + $body = purify_html($body); $body = html2bbcode($body); } @@ -1348,6 +1373,7 @@ function get_atom_elements($feed,$item) { $arr = array('feed' => $feed, 'item' => $item, 'result' => $res); call_hooks('parse_atom', $arr); + logger('get_atom_elements: ' . print_r($res,true)); return $res; } @@ -2038,6 +2064,12 @@ function tag_deliver($uid,$item_id) { logger('tag_deliver: tag permission denied for ' . $u[0]['channel_address']); } + + $union = check_item_source($uid,$item); + if($union) + logger('check_item_source returns true'); + + // This might be a followup by the original post author to a tagged forum // If so setup a second delivery chain @@ -2104,42 +2136,44 @@ function tag_deliver($uid,$item_id) { intval(ITEM_MENTIONSME), intval($item_id) ); - } - else - return; - // At this point we've determined that the person receiving this post was mentioned in it. - // Now let's check if this mention was inside a reshare so we don't spam a forum + // At this point we've determined that the person receiving this post was mentioned in it or it is a union. + // Now let's check if this mention was inside a reshare so we don't spam a forum - $body = preg_replace('/\[share(.*?)\[\/share\]/','',$item['body']); + $body = preg_replace('/\[share(.*?)\[\/share\]/','',$item['body']); - $pattern = '/@\[zrl\=' . preg_quote($term['url'],'/') . '\]' . preg_quote($u[0]['channel_name'],'/') . '\[\/zrl\]/'; + $pattern = '/@\[zrl\=' . preg_quote($term['url'],'/') . '\]' . preg_quote($u[0]['channel_name'],'/') . '\[\/zrl\]/'; - if(! preg_match($pattern,$body,$matches)) { - logger('tag_deliver: mention was in a reshare - ignoring'); - return; - } + if(! preg_match($pattern,$body,$matches)) { + logger('tag_deliver: mention was in a reshare - ignoring'); + return; + } - // All good. - // Send a notification + // All good. + // Send a notification - require_once('include/enotify.php'); - notification(array( - 'to_xchan' => $u[0]['channel_hash'], - 'from_xchan' => $item['author_xchan'], - 'type' => NOTIFY_TAGSELF, - 'item' => $item, - 'link' => $i[0]['llink'], - 'verb' => ACTIVITY_TAG, - 'otype' => 'item' - )); + require_once('include/enotify.php'); + notification(array( + 'to_xchan' => $u[0]['channel_hash'], + 'from_xchan' => $item['author_xchan'], + 'type' => NOTIFY_TAGSELF, + 'item' => $item, + 'link' => $i[0]['llink'], + 'verb' => ACTIVITY_TAG, + 'otype' => 'item' + )); + + + if(! perm_is_allowed($uid,$item['author_xchan'],'tag_deliver')) { + logger('tag_delivery denied for uid ' . $uid . ' and xchan ' . $item['author_xchan']); + return; + } + } - if(! perm_is_allowed($uid,$item['author_xchan'],'tag_deliver')) { - logger('tag_delivery denied for uid ' . $uid . ' and xchan ' . $item['author_xchan']); + if((! $mention) && (! $union)) return; - } // tgroup delivery - setup a second delivery chain @@ -2248,6 +2282,73 @@ function tgroup_check($uid,$item) { } +/** + * @function check_item_source($uid,$item) + * @param $uid + * @param $item + * + * @description + * Checks to see if this item owner is referenced as a source for this channel and if the post + * matches the rules for inclusion in this channel. Returns true if we should create a second delivery + * chain and false if none of the rules apply, or if the item is private. + */ + + +function check_item_source($uid,$item) { + + if($item['item_private']) + return false; + + + $r = q("select * from source where src_channel_id = %d and src_xchan = '%s' limit 1", + intval($uid), + dbesc($item['owner_xchan']) + ); + + if(! $r) + return false; + + $x = q("select abook_their_perms from abook where abook_channel = %d and abook_xchan = '%s' limit 1", + intval($uid), + dbesc($item['owner_xchan']) + ); + + if(! $x) + return false; + + if(! ($x[0]['abook_their_perms'] & PERMS_A_REPUBLISH)) + return false; + + if($r[0]['src_channel_xchan'] === $item['owner_xchan']) + return false; + + if(! $r[0]['src_patt']) + return true; + + require_once('include/html2plain.php'); + $text = prepare_text($item['body'],$item['mimetype']); + $text = html2plain($text); + + $tags = ((count($items['term'])) ? $items['term'] : false); + + $words = explode("\n",$r[0]['src_patt']); + if($words) { + foreach($words as $word) { + if(substr($word,0,1) === '#' && $tags) { + foreach($tags as $t) + if($t['type'] == TERM_HASHTAG && substr($t,1) === $word) + return true; + } + if(stristr($text,$word) !== false) + return true; + } + } + return false; +} + + + + function mail_store($arr) { if(! $arr['channel_id']) { @@ -2576,6 +2677,9 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) logger('consume_feed: empty input'); return; } + + // Want to see this work as a content source for the matrix? + // Read this: https://github.com/friendica/red/wiki/Service_Federation $feed = new SimplePie(); $feed->set_raw_data($xml); @@ -2592,12 +2696,6 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) // Check at the feed level for updated contact name and/or photo - $name_updated = ''; - $new_name = ''; - $photo_timestamp = ''; - $photo_url = ''; - $birthday = ''; - // process any deleted entries @@ -2619,7 +2717,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) /* $r = q("SELECT `item`.*, `contact`.`self` FROM `item` left join `contact` on `item`.`contact-id` = `contact`.`id` WHERE `mid` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1", dbesc($mid), - intval($importer['uid']), + intval($importer['channel_id']), intval($contact['id']) ); */ @@ -2637,7 +2735,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) dbesc($when), dbesc(datetime_convert()), dbesc($item['mid']), - intval($importer['uid']) + intval($importer['channel_id']) ); } else { @@ -2648,7 +2746,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) dbesc($when), dbesc(datetime_convert()), dbesc($mid), - intval($importer['uid']) + intval($importer['channel_id']) ); } } @@ -2673,6 +2771,9 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) $is_reply = false; $item_id = $item->get_id(); + +logger('consume_feed: processing ' . $item_id); + $rawthread = $item->get_item_tags( NAMESPACE_THREAD,'in-reply-to'); if(isset($rawthread[0]['attribs']['']['ref'])) { $is_reply = true; @@ -2684,11 +2785,6 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) if($pass == 1) continue; - // not allowed to post -// FIXME - check permissions -// if($contact['rel'] == CONTACT_IS_FOLLOWER) -// continue; - // Have we seen it? If not, import it. @@ -2710,12 +2806,12 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) $r = q("SELECT `uid`, `edited`, `body` FROM `item` WHERE `mid` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), - intval($importer['uid']) + intval($importer['channel_id']) ); // Update content if 'updated' changes - if(count($r)) { + if($r) { if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { // do not accept (ignore) an earlier edit than one we currently have. @@ -2727,7 +2823,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) dbesc($datarray['body']), dbesc(datetime_convert('UTC','UTC',$datarray['edited'])), dbesc($item_id), - intval($importer['uid']) + intval($importer['channel_id']) ); } @@ -2736,7 +2832,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) $datarray['parent_mid'] = $parent_mid; - $datarray['uid'] = $importer['uid']; + $datarray['uid'] = $importer['channel_id']; $datarray['contact-id'] = $contact['id']; if((activity_match($datarray['verb'],ACTIVITY_LIKE)) || (activity_match($datarray['verb'],ACTIVITY_DISLIKE))) { $datarray['type'] = 'activity'; @@ -2760,7 +2856,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) if($xt->type == ACTIVITY_OBJ_NOTE) { $r = q("select * from item where `mid` = '%s' AND `uid` = %d limit 1", dbesc($xt->id), - intval($importer['importer_uid']) + intval($importer['channel_id']) ); if(! count($r)) continue; @@ -2778,7 +2874,9 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) } } - $xx = item_store($datarray); +logger('consume_feed: ' . print_r($datarray,true)); + +// $xx = item_store($datarray); $r = $xx['item_id']; continue; } @@ -2810,7 +2908,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) if((x($datarray,'obj_type')) && ($datarray['obj_type'] === ACTIVITY_OBJ_EVENT)) { $ev = bbtoevent($datarray['body']); if(x($ev,'desc') && x($ev,'start')) { - $ev['uid'] = $importer['uid']; + $ev['uid'] = $importer['channel_id']; $ev['mid'] = $item_id; $ev['edited'] = $datarray['edited']; $ev['private'] = $datarray['private']; @@ -2819,23 +2917,23 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) $ev['cid'] = $contact['id']; $r = q("SELECT * FROM `event` WHERE `mid` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), - intval($importer['uid']) + intval($importer['channel_id']) ); if(count($r)) $ev['id'] = $r[0]['id']; - $xyz = event_store($ev); +// $xyz = event_store($ev); continue; } } $r = q("SELECT `uid`, `edited`, `body` FROM `item` WHERE `mid` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), - intval($importer['uid']) + intval($importer['channel_id']) ); // Update content if 'updated' changes - if(count($r)) { + if($r) { if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { // do not accept (ignore) an earlier edit than one we currently have. @@ -2847,7 +2945,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) dbesc($datarray['body']), dbesc(datetime_convert('UTC','UTC',$datarray['edited'])), dbesc($item_id), - intval($importer['uid']) + intval($importer['channel_id']) ); } @@ -2875,8 +2973,8 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) } - if(! is_array($contact)) - return; +// if(! is_array($contact)) +// return; // This is my contact on another system, but it's really me. @@ -2887,7 +2985,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) } $datarray['parent_mid'] = $item_id; - $datarray['uid'] = $importer['uid']; + $datarray['uid'] = $importer['channel_id']; $datarray['contact-id'] = $contact['id']; if(! link_compare($datarray['owner-link'],$contact['url'])) { @@ -2905,17 +3003,20 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) // posting an @-tag delivery, which followers are allowed to do for certain // page types. Now that we've parsed the post, let's check if it is legit. Otherwise ignore it. - if(($contact['rel'] == CONTACT_IS_FOLLOWER) && (! tgroup_check($importer['uid'],$datarray))) + if(($contact['rel'] == CONTACT_IS_FOLLOWER) && (! tgroup_check($importer['channel_id'],$datarray))) continue; +logger('consume_feed: ' . print_r($datarray,true)); - $xx = item_store($datarray); +// $xx = item_store($datarray); $r = $xx['item_id']; continue; } } } + + } @@ -3670,9 +3771,9 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C } elseif($arr['cid'] && $uid) { - $r = q("SELECT * from abook where abook_id = %d and abook_channel = %d and not ( abook_flags & " . intval(ABOOK_FLAG_BLOCKED) . ") limit 1", + $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d and not ( abook_flags & " . intval(ABOOK_FLAG_BLOCKED) . ") limit 1", intval($arr['cid']), - intval($uid) + intval(local_user()) ); if($r) { $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval($arr['uid']) . " AND ( author_xchan = '" . dbesc($r[0]['abook_xchan']) . "' or owner_xchan = '" . dbesc($r[0]['abook_xchan']) . "' ) and item_restrict = 0 ) "; @@ -3853,4 +3954,4 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C } return $items; -}
\ No newline at end of file +} diff --git a/include/onedirsync.php b/include/onedirsync.php new file mode 100644 index 000000000..b9c17628a --- /dev/null +++ b/include/onedirsync.php @@ -0,0 +1,42 @@ +<?php /** @file */ + +require_once('boot.php'); +require_once('include/cli_startup.php'); +require_once('include/zot.php'); +require_once('include/dir_fns.php'); + + +function onedirsync_run($argv, $argc){ + + + cli_startup(); + $a = get_app(); + + logger('onedirsync: start'); + + if(($argc > 1) && (intval($argv[1]))) + $update_id = intval($argv[1]); + + if(! $update_id) { + logger('onedirsync: no update'); + return; + } + + $r = q("select * from updates where ud_id = %d limit 1", + intval($update_id) + ); + + if(! $r) + return; + if($r['ud_flags'] & UPDATE_FLAGS_UPDATED) + return; + + update_directory_entry($r[0]); + + return; +} + +if (array_search(__file__,get_included_files())===0){ + onedirsync_run($argv,$argc); + killme(); +} diff --git a/include/page_widgets.php b/include/page_widgets.php index 23d6d25ba..d70281afc 100644 --- a/include/page_widgets.php +++ b/include/page_widgets.php @@ -5,7 +5,7 @@ function writepages_widget ($who,$which){ return replace_macros(get_markup_template('write_pages.tpl'), array( '$new' => t('New Page'), '$newurl' => "webpages/$who", - '$edit' => t('edit'), + '$edit' => t('Edit'), '$editurl' => "editwebpage/$who/$which" )); } diff --git a/include/permissions.php b/include/permissions.php index bf50ebdd1..45ea7c3eb 100644 --- a/include/permissions.php +++ b/include/permissions.php @@ -28,6 +28,7 @@ function get_perms() { 'write_storage' => array('channel_w_storage', intval(PERMS_W_STORAGE), false, t('Can write to my "public" file storage'), ''), 'write_pages' => array('channel_w_pages', intval(PERMS_W_PAGES), false, t('Can edit my "public" pages'), ''), + 'republish' => array('channel_a_republish', intval(PERMS_A_REPUBLISH), false, t('Can source my "public" posts in derived channels'), t('Somewhat advanced - very useful in open communities')), 'delegate' => array('channel_a_delegate', intval(PERMS_A_DELEGATE), false, t('Can administer my channel resources'), t('Extremely advanced. Leave this alone unless you know what you are doing')), ); $ret = array('global_permissions' => $global_perms); diff --git a/include/poller.php b/include/poller.php index f084005c7..05584a05d 100644 --- a/include/poller.php +++ b/include/poller.php @@ -69,6 +69,8 @@ function poller_run($argv, $argc){ $d1 = get_config('system','last_expire_day'); $d2 = intval(datetime_convert('UTC','UTC','now','d')); + $dirmode = get_config('system','directory_mode'); + if($d2 != intval($d1)) { // If this is a directory server, request a sync with an upstream @@ -76,7 +78,6 @@ function poller_run($argv, $argc){ // Pull remote changes and push local changes. // potential issue: how do we keep from creating an endless update loop? - $dirmode = get_config('system','directory_mode'); if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) { require_once('include/dir_fns.php'); sync_directories($dirmode); @@ -171,76 +172,95 @@ function poller_run($argv, $argc){ ); - if(! $contacts) { - return; - } + if($contacts) { - foreach($contacts as $contact) { + foreach($contacts as $contact) { - $update = false; + $update = false; - $t = $contact['abook_updated']; - $c = $contact['abook_connected']; + $t = $contact['abook_updated']; + $c = $contact['abook_connected']; - if($c == $t) { - if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) - $update = true; - } - else { - // if we've never connected with them, start the mark for death countdown from now - - if($c == '0000-00-00 00:00:00') { - $r = q("update abook set abook_connected = '%s' where abook_id = %d limit 1", - dbesc(datetime_convert()), - intval($contact['abook_id']) - ); - $c = datetime_convert(); - $update = true; + if($c == $t) { + if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) + $update = true; } + else { + // if we've never connected with them, start the mark for death countdown from now + + if($c == '0000-00-00 00:00:00') { + $r = q("update abook set abook_connected = '%s' where abook_id = %d limit 1", + dbesc(datetime_convert()), + intval($contact['abook_id']) + ); + $c = datetime_convert(); + $update = true; + } + + // He's dead, Jim + + if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 30 day")) > 0) { + $r = q("update abook set abook_flags = (abook_flags | %d) where abook_id = %d limit 1", + intval(ABOOK_FLAG_ARCHIVED), + intval($contact['abook_id']) + ); + $update = false; + continue; + } + + if($contact['abook_flags'] & ABOOK_FLAG_ARCHIVED) { + $update = false; + continue; + } + + // might be dead, so maybe don't poll quite so often + + // recently deceased, so keep up the regular schedule for 3 days + + if((strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 3 day")) > 0) + && (strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 1 day")) > 0)) + $update = true; - // He's dead, Jim + // After that back off and put them on a morphine drip + + if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 2 day")) > 0) { + $update = true; + } - if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 30 day")) > 0) { - $r = q("update abook set abook_flags = (abook_flags | %d) where abook_id = %d limit 1", - intval(ABOOK_FLAG_ARCHIVED), - intval($contact['abook_id']) - ); - $update = false; - continue; - } - if($contact['abook_flags'] & ABOOK_FLAG_ARCHIVED) { - $update = false; - continue; } - // might be dead, so maybe don't poll quite so often + if((! $update) && (! $force)) + continue; - // recently deceased, so keep up the regular schedule for 3 days - - if((strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 3 day")) > 0) - && (strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 1 day")) > 0)) - $update = true; + proc_run('php','include/onepoll.php',$contact['abook_id']); + if($interval) + @time_sleep_until(microtime(true) + (float) $interval); - // After that back off and put them on a morphine drip + } + } - if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 2 day")) > 0) { - $update = true; + if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) { + $r = q("select ud_id from updates where not ( ud_flags & %d ) and ( ud_last = '0000-00-00 00:00:00' OR ud_last > UTC_TIMESTAMP() - INTERVAL 7 DAYS) ", + intval(UPDATE_FLAGS_UPDATED) + ); + if($r) { + foreach($r as $rr) { + + // If they didn't respond when we attempted before, back off to once a day + // After 7 days we won't bother anymore + + if($rr['ud_last'] != '0000-00-00 00:00:00') + if($rr['ud_last'] > datetime_convert('UTC','UTC', 'now - 1 day')) + continue; + proc_run('php','include/onedirsync.php',$rr['ud_id']); + if($interval) + @time_sleep_until(microtime(true) + (float) $interval); } - - } - - if((! $update) && (! $force)) - continue; - - proc_run('php','include/onepoll.php',$contact['abook_id']); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - } - + return; } diff --git a/include/security.php b/include/security.php index 4738e473b..1181e6bf2 100644 --- a/include/security.php +++ b/include/security.php @@ -302,16 +302,19 @@ function public_permissions_sql($observer_hash) { foreach($groups as $g) $gs .= '|<' . $g . '>'; } - $sql = sprintf( - " OR (( NOT (deny_cid like '%s' OR deny_gid REGEXP '%s') - AND ( allow_cid like '%s' OR allow_gid REGEXP '%s' OR ( allow_cid = '' AND allow_gid = '') ) - )) - ", - dbesc(protect_sprintf( '%<' . $observer_hash . '>%')), - dbesc($gs), - dbesc(protect_sprintf( '%<' . $observer_hash . '>%')), - dbesc($gs) - ); + $sql = ''; + if($observer_hash) { + $sql = sprintf( + " OR (( NOT (deny_cid like '%s' OR deny_gid REGEXP '%s') + AND ( allow_cid like '%s' OR allow_gid REGEXP '%s' OR ( allow_cid = '' AND allow_gid = '') ) + )) + ", + dbesc(protect_sprintf( '%<' . $observer_hash . '>%')), + dbesc($gs), + dbesc(protect_sprintf( '%<' . $observer_hash . '>%')), + dbesc($gs) + ); + } return $sql; } @@ -409,7 +412,7 @@ function stream_perms_api_uids($perms_min = PERMS_SITE) { $ret = array(); if(local_user()) $ret[] = local_user(); - $r = q("select channel_id from channel where channel_r_stream <= %d", + $r = q("select channel_id from channel where channel_r_stream > 0 and channel_r_stream <= %d", intval($perms_min) ); if($r) @@ -424,6 +427,30 @@ function stream_perms_api_uids($perms_min = PERMS_SITE) { $str .= ','; $str .= intval($rr); } +logger('stream_perms_api_uids: ' . $str); return $str; } +function stream_perms_xchans($perms_min = PERMS_SITE) { + $ret = array(); + if(local_user()) + $ret[] = get_observer_hash(); + + $r = q("select channel_hash from channel where channel_r_stream > 0 and channel_r_stream <= %d", + intval($perms_min) + ); + if($r) + foreach($r as $rr) + if(! in_array($rr['channel_hash'],$ret)) + $ret[] = $rr['channel_hash']; + + $str = ''; + if($ret) + foreach($ret as $rr) { + if($str) + $str .= ','; + $str .= "'" . dbesc($rr) . "'"; + } +logger('stream_perms_xchans: ' . $str); + return $str; +} diff --git a/include/text.php b/include/text.php index 40df8bd89..69c258488 100755 --- a/include/text.php +++ b/include/text.php @@ -1312,7 +1312,7 @@ function get_plink($item) { $a = get_app(); if (x($item,'plink') && ($item['item_private'] != 1)) { return array( - 'href' => $item['plink'], + 'href' => zid($item['plink']), 'title' => t('link to source'), ); } @@ -1835,16 +1835,17 @@ function json_decode_plus($s) { function design_tools() { -// FIXME - this should be a template - - $o = '<div class="widget design-tools">'; - $o .= '<h3>' . t('Design') . '</h3>'; - $o .= '<a href="blocks">' . t('Blocks') . '</a>' . EOL; - $o .= '<a href="menu">' . t('Menus') . '</a>' . EOL; - $o .= '<a href="layout">' . t('Layouts') . '</a>' . EOL; - $o .= '<a href="webpages">' . t('Pages') . '</a>' . EOL; - $o .= '</div>'; - return $o; +$channel = get_app()->get_channel(); +$who = $channel['channel_address']; + +return replace_macros(get_markup_template('design_tools.tpl'), array( + '$title' => t('Design'), + '$who' => $who, + '$blocks' => t('Blocks'), + '$menus' => t('Menus'), + '$layout' => t('Layouts'), + '$pages' => t('Pages') + )); } diff --git a/include/zot.php b/include/zot.php index efcc4abaa..33bb60c0f 100644 --- a/include/zot.php +++ b/include/zot.php @@ -411,7 +411,7 @@ function zot_register_hub($arr) { // If the xchan already exists, update the name and photo if these have changed. // -function import_xchan($arr) { +function import_xchan($arr,$ud_flags = 1) { $ret = array('success' => false); $dirmode = intval(get_config('system','directory_mode')); @@ -469,6 +469,11 @@ function import_xchan($arr) { else $new_flags = $r[0]['xchan_flags']; + $adult = (($r[0]['xchan_flags'] & XCHAN_FLAGS_SELFCENSORED) ? true : false); + $adult_changed = ((intval($adult) != intval($arr['adult_content'])) ? true : false); + if($adult_changed) + $new_flags = $new_flags ^ XCHAN_FLAGS_SELFCENSORED; + if(($r[0]['xchan_name_date'] != $arr['name_updated']) || ($r[0]['xchan_connurl'] != $arr['connections_url']) @@ -511,6 +516,8 @@ function import_xchan($arr) { $new_flags = XCHAN_FLAGS_HIDDEN; else $new_flags = 0; + if($arr['adult_content']) + $new_flags |= XCHAN_FLAGS_SELFCENSORED; $x = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_mimetype, xchan_photo_l, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_flags) @@ -681,7 +688,7 @@ function import_xchan($arr) { if($dirmode != DIRECTORY_MODE_NORMAL) { if(array_key_exists('profile',$arr) && is_array($arr['profile'])) { - $profile_changed = import_directory_profile($xchan_hash,$arr['profile']); + $profile_changed = import_directory_profile($xchan_hash,$arr['profile'],$arr['address'],$ud_flags, 1); if($profile_changed) { $what .= 'profile '; $changed = true; @@ -711,7 +718,7 @@ function import_xchan($arr) { if($changed) { $guid = random_string() . '@' . get_app()->get_hostname(); - update_modtime($xchan_hash,$guid); + update_modtime($xchan_hash,$guid,$arr['address'],$ud_flags); logger('import_xchan: changed: ' . $what,LOGGER_DEBUG); } @@ -781,10 +788,6 @@ function zot_fetch($arr) { logger('zot_fetch: no hub: ' . print_r($arr['sender'],true)); return; } - - - $ret_secret = json_encode(array($arr['secret'],'secret_sig' => base64url_encode(rsa_sign($arr['secret'],get_config('system','prvkey'))))); - $data = array( 'type' => 'pickup', @@ -795,7 +798,6 @@ function zot_fetch($arr) { 'secret_sig' => base64url_encode(rsa_sign($arr['secret'],get_config('system','prvkey'))) ); - $datatosend = json_encode(aes_encapsulate(json_encode($data),$ret_hub['hubloc_sitekey'])); $fetch = zot_zot($url,$datatosend); @@ -1364,7 +1366,12 @@ function process_profile_delivery($sender,$arr,$deliveries) { // deliveries is irrelevant, what to do about birthday notification....? logger('process_profile_delivery', LOGGER_DEBUG); - import_directory_profile($sender['hash'],$arr); + + $r = q("select xchan_addr from xchan where xchan_hash = '%s' limit 1", + dbesc($sender['hash']) + ); + if($r) + import_directory_profile($sender['hash'],$arr,$r[0]['xchan_addr'], 1, 0); } @@ -1375,7 +1382,7 @@ function process_profile_delivery($sender,$arr,$deliveries) { * */ -function import_directory_profile($hash,$profile) { +function import_directory_profile($hash,$profile,$addr,$ud_flags = 1, $suppress_update = 0) { logger('import_directory_profile', LOGGER_DEBUG); if(! $hash) @@ -1410,9 +1417,10 @@ function import_directory_profile($hash,$profile) { // Self censored, make it so // These are not translated, so the German "erwachsenen" keyword will not censor the directory profile. Only the English form - "adult". + if(in_arrayi('nsfw',$clean) || in_arrayi('adult',$clean)) { q("update xchan set xchan_flags = (xchan_flags | %d) where xchan_hash = '%s' limit 1", - intval(XCHAN_FLAGS_CENSORED), + intval(XCHAN_FLAGS_SELFCENSORED), dbesc($hash) ); } @@ -1481,8 +1489,8 @@ function import_directory_profile($hash,$profile) { $d = array('xprof' => $arr, 'profile' => $profile, 'update' => $update); call_hooks('import_directory_profile', $d); - if($d['update']) - update_modtime($arr['xprof_hash'],random_string() . '@' . get_app()->get_hostname()); + if(($d['update']) && (! $suppress_update)) + update_modtime($arr['xprof_hash'],random_string() . '@' . get_app()->get_hostname(), $addr, $ud_flags); return $d['update']; } @@ -1522,12 +1530,23 @@ function import_directory_keywords($hash,$keywords) { } -function update_modtime($hash,$guid) { - q("insert into updates (ud_hash, ud_guid, ud_date) values ( '%s', '%s', '%s' )", - dbesc($hash), - dbesc($guid), - dbesc(datetime_convert()) - ); +function update_modtime($hash,$guid,$addr,$flags = 0) { + + if($flags) { + q("insert into updates (ud_hash, ud_guid, ud_date, ud_flags, ud_addr ) values ( '%s', '%s', '%s', %d, '%s' )", + dbesc($hash), + dbesc($guid), + dbesc(datetime_convert()), + intval($flags), + dbesc($addr) + ); + } + else { + q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and not (ud_flags & %d) ", + intval(UPDATE_FLAGS_UPDATED), + intval(UPDATE_FLAGS_UPDATED) + ); + } } |