diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/activities.php | 125 | ||||
-rw-r--r-- | include/channel.php | 3 | ||||
-rw-r--r-- | include/contact_widgets.php | 2 | ||||
-rw-r--r-- | include/dba/dba_transaction.php | 64 | ||||
-rw-r--r-- | include/items.php | 56 | ||||
-rw-r--r-- | include/photo/photo_driver.php | 9 | ||||
-rw-r--r-- | include/taxonomy.php | 4 | ||||
-rw-r--r-- | include/text.php | 2 |
8 files changed, 136 insertions, 129 deletions
diff --git a/include/activities.php b/include/activities.php index f5f0e55da..c06a8f6c4 100644 --- a/include/activities.php +++ b/include/activities.php @@ -1,100 +1,83 @@ <?php /** @file */ -function profile_activity($changed, $value) { - - // TODO: we should probably send an Update/Profile or Person activity here. - // We could also just send a Note with some changed info? - // Profiles are currently a hubzilla specific thing. - return; +use Zotlabs\Lib\Activity; +use Zotlabs\Daemon\Master; - if(! local_channel() || ! is_array($changed) || ! count($changed)) - return; +function profile_activity($changed, $value) { - if(! get_pconfig(local_channel(),'system','post_profilechange')) + if (!local_channel() || !is_array($changed) || !count($changed)) { return; + } - require_once('include/items.php'); - - $self = App::get_channel(); - - if(! count($self)) + if (!get_pconfig(local_channel(), 'system', 'post_profilechange')) { return; + } - $arr = array(); - $arr['uuid'] = item_message_id(); - $arr['mid'] = $arr['parent_mid'] = z_root() . '/item/' . $arr['uuid']; - $arr['uid'] = local_channel(); - $arr['aid'] = $self['channel_account_id']; - $arr['owner_xchan'] = $arr['author_xchan'] = $self['xchan_hash']; - - $arr['item_wall'] = 1; - $arr['item_origin'] = 1; - $arr['item_thread_top'] = 1; - $arr['verb'] = ACTIVITY_UPDATE; - $arr['obj_type'] = 'Profile'; - - $arr['plink'] = z_root() . '/channel/' . $self['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']); + $channel = App::get_channel(); - $A = '[url=' . z_root() . '/channel/' . $self['channel_address'] . ']' . $self['channel_name'] . '[/url]'; + $arr['verb'] = 'Update'; + $arr['obj_type'] = 'Profile'; + $channel_link = '[url=' . z_root() . '/channel/' . $channel['channel_address'] . ']' . $channel['channel_name'] . '[/url]'; $changes = ''; $t = count($changed); $z = 0; - foreach($changed as $ch) { - if(strlen($changes)) { - if ($z == ($t - 1)) + $photo = false; + foreach ($changed as $ch) { + if (strlen($changes)) { + if ($z == ($t - 1)) { $changes .= t(' and '); - else - $changes .= ', '; + } else { + $changes .= t(', '); + } } - $z ++; + + if (in_array($ch, [t('Profile Photo'), t('Cover Photo')])) { + $photo = true; + $photo_size = (($ch === t('Profile Photo')) ? 4 : 8); + } + + $z++; $changes .= $ch; } - $prof = '[url=' . z_root() . '/profile/' . $self['channel_address'] . ']' . t('public profile') . '[/url]'; + $profile_link = '[url=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . t('public profile') . '[/url]'; - if($t == 1 && strlen($value)) { + if ($t == 1 && strlen($value)) { // if it's a url, the HTML quotes will mess it up, so link it and don't try and zidify it because we don't know what it points to. - $value = preg_replace_callback("/([^\]\='".'"'."]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,]+)/ismu", 'red_zrl_callback', $value); + $value = preg_replace_callback("/([^='" . '"' . "]|^|#\^)(https?:\/\/[a-zA-Z0-9\pL:\/\-?&;.=@_~#%\$!+,]+)/ismu", 'red_zrl_callback', $value); // take out the bookmark indicator - if(substr($value,0,2) === '#^') - $value = str_replace('#^','',$value); - - $message = sprintf( t('%1$s changed %2$s to “%3$s”'), $A, $changes, $value); - $message .= "\n\n" . sprintf( t('Visit %1$s\'s %2$s'), $A, $prof); - } - else - $message = sprintf( t('%1$s has an updated %2$s, changing %3$s.'), $A, $prof, $changes); - - - $arr['body'] = $message; - - $links = array(); - $links[] = array('rel' => 'alternate', 'type' => 'text/html', - 'href' => z_root() . '/profile/' . $self['channel_address']); - $links[] = array('rel' => 'photo', 'type' => $self['xchan_photo_mimetype'], - 'href' => $self['xchan_photo_l']); + if (str_starts_with($value, '#^')) { + $value = str_replace('#^', '', $value); + } - $arr['object'] = json_encode(array( - 'type' => 'Profile', - 'title' => $self['channel_name'], - 'id' => $self['xchan_url'] . '/' . $self['xchan_hash'], - 'link' => $links - )); + if ($photo) { + $value = "\n\n" . '[zmg=' . z_root() . '/photo/' . $value . '-' . $photo_size . ']' . $ch . ' ' . $channel['xchan_name'] . '[/zmg]'; + } + else { + $value = '"' . $value . '"'; + } + $message = sprintf(t('%1$s %2$s has been updated to %3$s.'), $channel_link . '\'s' . (($photo) ? '' : ' ' . $profile_link), strtolower($changes), $value); - $arr['allow_cid'] = $self['channel_allow_cid']; - $arr['allow_gid'] = $self['channel_allow_gid']; - $arr['deny_cid'] = $self['channel_deny_cid']; - $arr['deny_gid'] = $self['channel_deny_gid']; + } else { + $message = sprintf(t('%1$s updated the %2$s. Changed %3$s.'), $channel_link, $profile_link, strtolower($changes)); + } - $res = item_store($arr); - $i = $res['item_id']; + $arr['body'] = $message; - if($i) { - // FIXME - limit delivery in notifier.php to those specificed in the perms argument - Zotlabs\Daemon\Master::Summon(array('Notifier','activity', $i, 'PERMS_R_PROFILE')); - } + $arr['obj'] = [ + 'type' => 'Profile', + 'content' => bbcode($message), + 'source' => [ + 'content' => $message, + 'mediaType' => 'text/bbcode' + ], + 'describes' => Activity::encode_person($channel), + 'url' => z_root() . '/profile/' . $channel['channel_address'] + ]; + + post_activity_item($arr); } diff --git a/include/channel.php b/include/channel.php index b8affa3ca..a82794bfd 100644 --- a/include/channel.php +++ b/include/channel.php @@ -1771,6 +1771,7 @@ function advanced_profile() { if(App::$profile['gender']) $profile['gender'] = array( t('Gender:'), App::$profile['gender'] ); $ob_hash = get_observer_hash(); +/* TODO: AS2 compatibility if($ob_hash && perm_is_allowed(App::$profile['profile_uid'],$ob_hash,'post_like')) { $profile['canlike'] = true; $profile['likethis'] = t('Like this channel'); @@ -1790,7 +1791,7 @@ function advanced_profile() { foreach($likers as $l) $profile['likers'][] = array('name' => $l['xchan_name'],'photo' => zid($l['xchan_photo_s']), 'url' => zid($l['xchan_url'])); } - +*/ if((App::$profile['dob']) && (App::$profile['dob'] != '0000-00-00')) { $val = ''; diff --git a/include/contact_widgets.php b/include/contact_widgets.php index 182f674ca..c05ecaf7c 100644 --- a/include/contact_widgets.php +++ b/include/contact_widgets.php @@ -85,7 +85,7 @@ function categories_widget($baseurl,$selected = '') { AND term.otype = %d AND item.owner_xchan = '%s' AND item.item_wall = 1 - AND item.verb != '%s' + AND item.verb NOT IN ('Update', '%s') $item_normal $sql_extra ORDER BY term.term ASC", diff --git a/include/dba/dba_transaction.php b/include/dba/dba_transaction.php new file mode 100644 index 000000000..02e9945ca --- /dev/null +++ b/include/dba/dba_transaction.php @@ -0,0 +1,64 @@ +<?php +/** + * Class to represent a database transaction. + * + * A database transaction is initiated upon construction of an object of this + * class. The transaction will be automatically rolled back upon destruction + * unless it has been explicitly committed by calling the `commit` method. + * + * Wrapping multiple database operation within a transaction ensures that all + * (or none) of the operations are successfully completed at the same time. + * + * If a transaction is already active when constructing an object of this + * class, it will _not_ try to initiate a transaction, but constructs an object + * that will in practice be a stub. This prevents that "nested" transactions + * will cause problems with the existing active transaction. + * + * It also means that any rollbacks or commits perfomed on the "nested" + * transaction will be ignored, and postponed to the outer transaction is + * committed or rolled back. + * + * Also note that any modification to the database schema will implicitly + * commit active transactions in most cases, so be careful about relying on + * transactions in those cases. + * + * @Note This class assumes the actual underlying database driver is PDO. + */ +class DbaTransaction { + private bool $committed = false; + private bool $active = false; + + /** + * Creates a database transaction object. + * + * If a transaction is already active for this db connection, + * no transaction is initiated, and the constructed object will + * not perform any commit or rollback actions. + */ + public function __construct(private dba_driver $dba) { + if (! $this->dba->db->inTransaction()) { + $this->active = $this->dba->db->beginTransaction(); + } + } + + /** + * Roll back the transaction if it is active and not already committed. + */ + public function __destruct() { + if ($this->active && ! $this->committed) { + $this->dba->db->rollBack(); + } + } + + /** + * Commit the transaction if active. + * + * This will also mark the transaction as committed, preventing it from + * being attempted rolled back on destruction. + */ + public function commit(): void { + if ($this->active && ! $this->committed) { + $this->committed = $this->dba->db->commit(); + } + } +} diff --git a/include/items.php b/include/items.php index 8a0af5679..e26366af5 100644 --- a/include/items.php +++ b/include/items.php @@ -459,7 +459,7 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) { if(! $arr['mid']) { - $arr['uuid'] = ((x($arr,'uuid')) ? $arr['uuid'] : item_message_id()); + $arr['uuid'] = ((x($arr,'uuid')) ? $arr['uuid'] : new_uuid()); } $arr['mid'] = ((x($arr,'mid')) ? $arr['mid'] : z_root() . '/item/' . $arr['uuid']); $arr['parent_mid'] = ((x($arr,'parent_mid')) ? $arr['parent_mid'] : $arr['mid']); @@ -520,7 +520,7 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) { return $ret; if($post_id && $deliver) { - Master::Summon([ 'Notifier','activity',$post_id ]); + Master::Summon(['Notifier','activity', $post_id]); } $ret['success'] = true; @@ -2487,7 +2487,7 @@ function send_status_notifications($post_id,$item) { // check for an unfollow thread activity - we should probably decode the obj and check the id // but it will be extremely rare for this to be wrong. - if(($xx['verb'] === ACTIVITY_UNFOLLOW) + if((in_array($xx['verb'], ['Ignore', ACTIVITY_UNFOLLOW])) && (in_array($xx['obj_type'], ['Note', 'Image', ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_PHOTO])) && ($xx['parent'] != $xx['id'])) $unfollowed = true; @@ -2514,7 +2514,6 @@ function send_status_notifications($post_id,$item) { if(! $notify) return; - Enotify::submit(array( 'type' => $type, 'from_xchan' => $item['author_xchan'], @@ -4377,7 +4376,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C $item_normal = item_normal(); if (! (isset($arr['include_follow']) && intval($arr['include_follow']))) { - $item_normal .= sprintf(" and not verb in ('%s', '%s') ", + $item_normal .= sprintf(" and not verb in ('Follow', 'Ignore', '%s', '%s') ", dbesc(ACTIVITY_FOLLOW), dbesc(ACTIVITY_UNFOLLOW) ); @@ -4790,54 +4789,7 @@ function comment_local_origin($item) { return false; } - - -function send_profile_photo_activity($channel,$photo,$profile) { - - // for now only create activities for the default profile - - if(! intval($profile['is_default'])) - return; - - $arr = array(); - $arr['item_thread_top'] = 1; - $arr['item_origin'] = 1; - $arr['item_wall'] = 1; - - if(stripos($profile['gender'],t('female')) !== false) - $t = t('%1$s updated her %2$s'); - elseif(stripos($profile['gender'],t('male')) !== false) - $t = t('%1$s updated his %2$s'); - else - $t = t('%1$s updated their %2$s'); - - $ptext = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']' . t('profile photo') . '[/zrl]'; - - $ltext = '[zrl=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . '[zmg=150x150]' . z_root() . '/photo/' . $photo['resource_id'] . '-4[/zmg][/zrl]'; - - $arr['body'] = sprintf($t,$channel['channel_name'],$ptext) . "\n\n" . $ltext; - - $acl = new Zotlabs\Access\AccessList($channel); - $x = $acl->get(); - - $arr['allow_cid'] = $x['allow_cid']; - - $arr['allow_gid'] = $x['allow_gid']; - $arr['deny_cid'] = $x['deny_cid']; - $arr['deny_gid'] = $x['deny_gid']; - - $arr['uid'] = $channel['channel_id']; - $arr['aid'] = $channel['channel_account_id']; - - $arr['owner_xchan'] = $channel['channel_hash']; - $arr['author_xchan'] = $channel['channel_hash']; - - post_activity_item($arr); -} - - function sync_an_item($channel_id,$item_id) { - $r = q("select * from item where id = %d", intval($item_id) ); diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php index 522e638de..4394d3238 100644 --- a/include/photo/photo_driver.php +++ b/include/photo/photo_driver.php @@ -117,7 +117,14 @@ function guess_image_type($filename, $data = '') { $body = $data['body']; if ($body) { $image = new Imagick(); - $image->readImageBlob($body); + + try{ + $image->readImageBlob($body); + } catch (\Exception $e) { + logger('Imagick readImageBlob() exception:' . print_r($e, true)); + return $type; + } + $r = $image->identifyImage(); if ($r && is_array($r) && array_key_exists($r['mimetype'], $types)) $type = $r['mimetype']; diff --git a/include/taxonomy.php b/include/taxonomy.php index cfec8414a..90ccb6142 100644 --- a/include/taxonomy.php +++ b/include/taxonomy.php @@ -58,7 +58,7 @@ function term_item_parent_query($uid,$table,$s,$type = TERM_UNKNOWN, $type2 = '' $s = str_replace('*','%',$s); if($type2) { - $r = q("select parent from item left join term on term.oid = item.id where term.ttype in (%d, %d) and term.term like '%s' and term.uid = %d and term.otype = 1 and item.verb != '%s'", + $r = q("select parent from item left join term on term.oid = item.id where term.ttype in (%d, %d) and term.term like '%s' and term.uid = %d and term.otype = 1 and item.verb NOT IN ('Update', '%s')", intval($type), intval($type2), dbesc($s), @@ -67,7 +67,7 @@ function term_item_parent_query($uid,$table,$s,$type = TERM_UNKNOWN, $type2 = '' ); } else { - $r = q("select parent from item left join term on term.oid = item.id where term.ttype = %d and term.term like '%s' and term.uid = %d and term.otype = 1 and item.verb != '%s'", + $r = q("select parent from item left join term on term.oid = item.id where term.ttype = %d and term.term like '%s' and term.uid = %d and term.otype = 1 and item.verb NOT IN ('Update', '%s')", intval($type), dbesc($s), intval($uid), diff --git a/include/text.php b/include/text.php index d6256b75b..aa9650a25 100644 --- a/include/text.php +++ b/include/text.php @@ -1750,7 +1750,7 @@ function prepare_body(&$item,$attach = false,$opts = false) { } - $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'],['Create', ACTIVITY_POST, ACTIVITY_UPDATE, ACTIVITY_SHARE])) ? format_poll($item, $s, $opts) : false); + $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'],['Create', 'Update', ACTIVITY_POST, ACTIVITY_UPDATE, ACTIVITY_SHARE])) ? format_poll($item, $s, $opts) : false); if ($poll) { $s = $poll; } |