]> git.mxchange.org Git - friendica.git/commitdiff
Merge pull request #5946 from JonnyTischbein/move_include_security
authorHypolite Petovan <hypolite@mrpetovan.com>
Fri, 19 Oct 2018 12:55:08 +0000 (08:55 -0400)
committerGitHub <noreply@github.com>
Fri, 19 Oct 2018 12:55:08 +0000 (08:55 -0400)
Move and Split include/security

41 files changed:
boot.php
config/config.ini.php
config/dbstructure.json
include/conversation.php
include/enotify.php
mod/admin.php
mod/common.php
mod/community.php
mod/crepair.php
mod/editpost.php
mod/follow.php
mod/invite.php
mod/item.php
mod/parse_url.php
mod/ping.php
mod/register.php
mod/regmod.php
mod/unfollow.php
src/Content/Text/BBCode.php
src/Core/Protocol.php
src/Database/DBA.php
src/Model/Contact.php
src/Model/Conversation.php
src/Model/Item.php
src/Model/Register.php [new file with mode: 0644]
src/Model/User.php
src/Module/Itemsource.php [new file with mode: 0644]
src/Object/Post.php
src/Protocol/ActivityPub.php
src/Protocol/ActivityPub/Processor.php
src/Protocol/ActivityPub/Receiver.php
src/Protocol/ActivityPub/Transmitter.php
src/Protocol/Diaspora.php
src/Util/ParseUrl.php
src/Worker/Delivery.php
src/Worker/OnePoll.php
update.php
view/templates/contact_edit.tpl
view/templates/debug/itemsource.tpl [new file with mode: 0644]
view/theme/frio/templates/contact_edit.tpl
view/theme/vier/templates/contact_edit.tpl

index ea1b273f2e8f24fac000e355ce1293ee1bcab174..acbc737658c2a8d4aef307aee52092abc74c7008 100644 (file)
--- a/boot.php
+++ b/boot.php
@@ -41,7 +41,7 @@ define('FRIENDICA_PLATFORM',     'Friendica');
 define('FRIENDICA_CODENAME',     'The Tazmans Flax-lily');
 define('FRIENDICA_VERSION',      '2018.12-dev');
 define('DFRN_PROTOCOL_VERSION',  '2.23');
-define('DB_UPDATE_VERSION',      1287);
+define('DB_UPDATE_VERSION',      1288);
 define('NEW_UPDATE_ROUTINE_VERSION', 1170);
 
 /**
@@ -647,7 +647,7 @@ function killme()
 /**
  * @brief Redirect to another URL and terminate this process.
  */
-function goaway($path)
+function goaway($path = '')
 {
        if (strstr(normalise_link($path), 'http://')) {
                $url = $path;
index 8274399843e14380216462f4234afb8d694fbb00..ea3df52cbdbdbc11c36d5ab11ea8f23dbb50b026 100644 (file)
@@ -140,6 +140,10 @@ disable_url_validation = false
 ; Disable the exposition check against the remote haveibeenpwned API on password change.
 disable_password_exposed = false
 
+; disable_polling (Boolean)
+; Disable the polling of DFRN and OStatus contacts through onepoll.php.
+disable_polling = false
+
 ; dlogfile (Path)
 ; location of the developer log file.
 dlogfile =
index 51cb3ce4f3f84037259e6b1b39c84c9ac4b843f1..da1da7a66b1a295242db1cf7aaa4ff2af39765c2 100644 (file)
                "indexes": {
                        "PRIMARY": ["id"],
                        "uri-hash": ["UNIQUE", "uri-hash"],
-                       "uri": ["uri(191)"]
+                       "uri": ["uri(191)"],
+                       "uri-id": ["uri-id"]
                }
        },
        "item-content": {
                "indexes": {
                        "PRIMARY": ["id"],
                        "uri-plink-hash": ["UNIQUE", "uri-plink-hash"],
-                       "uri": ["uri(191)"]
+                       "uri": ["uri(191)"],
+                       "uri-id": ["uri-id"]
                }
        },
        "item-delivery-data": {
index 43854bb40f7b7e8d1486edb47d41e3a092fa7063..31920c2fcb163e4e7864cace513afa8148ce4cfe 100644 (file)
@@ -853,8 +853,8 @@ function item_photo_menu($item) {
 
        if ($cid && !$item['self']) {
                $poke_link = 'poke/?f=&c=' . $cid;
-               $contact_url = 'contacts/' . $cid;
-               $posts_link = 'contacts/' . $cid . '/posts';
+               $contact_url = 'contact/' . $cid;
+               $posts_link = 'contact/' . $cid . '/posts';
 
                if (in_array($network, [Protocol::DFRN, Protocol::DIASPORA])) {
                        $pm_url = 'message/new/' . $cid;
index d8e5614c171034ae4270eb5d38bceaddb765400b..6d8cef87947194eea4f23aeb15e68be772cf0d99 100644 (file)
@@ -84,7 +84,7 @@ function notification($params)
        // with $params['show_in_notification_page'] == false, the notification isn't inserted into
        // the database, and an email is sent if applicable.
        // default, if not specified: true
-       $show_in_notification_page = ((x($params, 'show_in_notification_page')) ? $params['show_in_notification_page']:true);
+       $show_in_notification_page = isset($params['show_in_notification_page']) ? $params['show_in_notification_page'] : true;
 
        $additional_mail_header = "";
        $additional_mail_header .= "Precedence: list\n";
index a60af3b1207d367e41ad4dad5122253564210f74..2714b0b86450e98d545a23e397f51f781a9b3208 100644 (file)
@@ -19,13 +19,14 @@ use Friendica\Database\DBA;
 use Friendica\Database\DBStructure;
 use Friendica\Model\Contact;
 use Friendica\Model\Item;
+use Friendica\Model\Register;
 use Friendica\Model\User;
 use Friendica\Module\Login;
 use Friendica\Module\Tos;
 use Friendica\Util\Arrays;
 use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Temporal;
 use Friendica\Util\Network;
+use Friendica\Util\Temporal;
 
 require_once 'include/enotify.php';
 require_once 'include/text.php';
@@ -34,11 +35,11 @@ require_once 'include/items.php';
 /**
  * @brief Process send data from the admin panels subpages
  *
- * This function acts as relais for processing the data send from the subpages
+ * This function acts as relay for processing the data send from the subpages
  * of the admin panel. Depending on the 1st parameter of the url (argv[1])
  * specialized functions are called to process the data from the subpages.
  *
- * The function itself does not return anything, but the subsequencely function
+ * The function itself does not return anything, but the subsequently function
  * return the HTML for the pages of the admin panel.
  *
  * @param App $a
@@ -896,8 +897,7 @@ function admin_page_summary(App $a)
 
        logger('accounts: ' . print_r($accounts, true), LOGGER_DATA);
 
-       $r = q("SELECT COUNT(`id`) AS `count` FROM `register`");
-       $pending = $r[0]['count'];
+       $pending = Register::getPendingCount();
 
        $r = q("SELECT COUNT(*) AS `total` FROM `queue` WHERE 1");
        $queue = (($r) ? $r[0]['total'] : 0);
@@ -913,10 +913,10 @@ function admin_page_summary(App $a)
        $r = q("SHOW variables LIKE 'max_allowed_packet'");
        $max_allowed_packet = (($r) ? $r[0]['Value'] : 0);
 
-       $server_settings = ['label' => L10n::t('Server Settings'), 
-                               'php' => ['upload_max_filesize' => ini_get('upload_max_filesize'), 
-                                                 'post_max_size' => ini_get('post_max_size'), 
-                                                 'memory_limit' => ini_get('memory_limit')], 
+       $server_settings = ['label' => L10n::t('Server Settings'),
+                               'php' => ['upload_max_filesize' => ini_get('upload_max_filesize'),
+                                                 'post_max_size' => ini_get('post_max_size'),
+                                                 'memory_limit' => ini_get('memory_limit')],
                                'mysql' => ['max_allowed_packet' => $max_allowed_packet]];
 
        $t = get_markup_template('admin/summary.tpl');
@@ -1793,11 +1793,7 @@ function admin_page_users(App $a)
        }
 
        /* get pending */
-       $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
-                                FROM `register`
-                                INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
-                                INNER JOIN `user` ON `register`.`uid` = `user`.`uid`;");
-
+       $pending = Register::getPending();
 
        /* get users */
        $total = q("SELECT COUNT(*) AS `total` FROM `user` WHERE 1");
index 25a6aef17a5cc602833514148f2be7e20639af88..0b51f20d73334190c45d98d2af1a7be86084618f 100644 (file)
@@ -48,9 +48,9 @@ function common_content(App $a)
 
                if (DBA::isResult($contact)) {
                        $vcard_widget = replace_macros(get_markup_template("vcard-widget.tpl"), [
-                               '$name' => htmlentities($contact['name']),
+                               '$name'  => htmlentities($contact['name']),
                                '$photo' => $contact['photo'],
-                               'url' => 'contacts/' . $cid
+                               'url'    => 'contact/' . $cid
                        ]);
 
                        if (!x($a->page, 'aside')) {
index 01cf3ec70b0807580e8caa30fbe32e0da48e4151..0eaccc0db0306ead6ead5241690d2f37e524408c 100644 (file)
@@ -11,6 +11,7 @@ use Friendica\Core\L10n;
 use Friendica\Core\PConfig;
 use Friendica\Database\DBA;
 use Friendica\Model\Contact;
+use Friendica\Model\Item;
 
 function community_init(App $a)
 {
@@ -226,19 +227,12 @@ function community_getitems($start, $itemspage, $content, $accounttype)
                return DBA::toArray($r);
        } elseif ($content == 'global') {
                if (!is_null($accounttype)) {
-                       $sql_accounttype = " AND `owner`.`contact-type` = ?";
-                       $values = [$accounttype, $start, $itemspage];
+                       $condition = ["`uid` = ? AND `owner`.`contact-type` = ?", 0, $accounttype];
                } else {
-                       $sql_accounttype = "";
-                       $values = [$start, $itemspage];
+                       $condition = ['uid' => 0];
                }
 
-               $r = DBA::p("SELECT `uri` FROM `thread`
-                               INNER JOIN `item` ON `item`.`id` = `thread`.`iid`
-                               INNER JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id`
-                               INNER JOIN `contact` AS `owner` ON `owner`.`id`=`item`.`owner-id`
-                               WHERE `thread`.`uid` = 0 AND NOT `author`.`hidden` AND NOT `author`.`blocked` $sql_accounttype
-                               ORDER BY `thread`.`commented` DESC LIMIT ?, ?", $values);
+               $r = Item::selectThreadForUser(0, ['uri'], $condition, ['order' => ['commented' => true], 'limit' => [$start, $itemspage]]);
                return DBA::toArray($r);
        }
 
index 13885cb49106adc94b44a2f1d60dd4a50c5e9cdd..1cf562d64cae885e45fd9e07f3939b3041e40224 100644 (file)
@@ -114,7 +114,7 @@ function crepair_content(App $a)
        $warning = L10n::t('<strong>WARNING: This is highly advanced</strong> and if you enter incorrect information your communications with this contact may stop working.');
        $info = L10n::t('Please use your browser \'Back\' button <strong>now</strong> if you are uncertain what to do on this page.');
 
-       $returnaddr = "contacts/$cid";
+       $returnaddr = "contact/$cid";
 
        $allow_remote_self = Config::get('system', 'allow_users_remote_self');
 
index d6493b3c0c1a8aa34f4d9c547ca1688fe3ca8759..780145ed3f72d885791cc6f6be7c1a3bfbe574d3 100644 (file)
@@ -21,20 +21,14 @@ function editpost_content(App $a)
        }
 
        $post_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
-       $return_url = (($a->argc > 2) ? base64_decode($a->argv[2]) : '');
 
        if (!$post_id) {
                notice(L10n::t('Item not found') . EOL);
                return;
        }
 
-       // Fallback to SESSION return_path
-       if (empty($return_url)) {
-               $return_url = $_SESSION['return_url'];
-       }
-
        $fields = ['allow_cid', 'allow_gid', 'deny_cid', 'deny_gid',
-               'type', 'body', 'title', 'file', 'wall', 'post-type'];
+               'type', 'body', 'title', 'file', 'wall', 'post-type', 'guid'];
 
        $item = Item::selectFirstForUser(local_user(), $fields, ['id' => $post_id, 'uid' => local_user()]);
 
@@ -92,7 +86,7 @@ function editpost_content(App $a)
 
        $o .= replace_macros($tpl, [
                '$is_edit' => true,
-               '$return_path' => $return_url,
+               '$return_path' => '/display/' . $item['guid'],
                '$action' => 'item',
                '$share' => L10n::t('Save'),
                '$upload' => L10n::t('Upload photo'),
index 04c279c5b6ab707f5995aa0c229e412613082d50..70dfb627ed6fabc15d26e5e15424aebf6bf4c0ef 100644 (file)
@@ -39,7 +39,7 @@ function follow_post(App $a)
                }
                goaway($return_url);
        } elseif ($result['cid']) {
-               goaway('contacts/' . $result['cid']);
+               goaway('contact/' . $result['cid']);
        }
 
        info(L10n::t('The contact could not be added.'));
index e73ef01edb48b1c6091c71b7c392a8ab6076ef32..7f479157f81afbf93d0a7463c7d0d9a4dbc99fd6 100644 (file)
@@ -60,14 +60,9 @@ function invite_post(App $a)
                }
 
                if ($invitation_only && ($invites_remaining || is_site_admin())) {
-                       $code = autoname(8) . srand(1000, 9999);
+                       $code = Friendica\Model\Register::createForInvitation();
                        $nmessage = str_replace('$invite_code', $code, $message);
 
-                       $r = q("INSERT INTO `register` (`hash`,`created`) VALUES ('%s', '%s') ",
-                               DBA::escape($code),
-                               DBA::escape(DateTimeFormat::utcNow())
-                       );
-
                        if (! is_site_admin()) {
                                $invites_remaining --;
                                if ($invites_remaining >= 0) {
index dc93a9f798aef0d560c8e1b6953528c2c0882f43..5d4a23caa7a28802a4c9f82210c07c5f640e9aa7 100644 (file)
@@ -1012,11 +1012,7 @@ function handle_tag(App $a, &$body, &$inform, &$str_tags, $profile_uid, $tag, $n
 
                        $profile = $contact["url"];
                        $alias   = $contact["alias"];
-                       $newname = $contact["nick"];
-
-                       if (($newname == "") || !in_array($contact["network"], [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::TWITTER, Protocol::STATUSNET])) {
-                               $newname = $contact["name"];
-                       }
+                       $newname = defaults($contact, "name", $contact["nick"]);
                }
 
                //if there is an url for this persons profile
index 40eddc3bdd5053afcd93e1581048d4f13f9baf1f..a14379e7096da14cbb13b86fb022c71dbd7a79b3 100644 (file)
@@ -73,6 +73,7 @@ function parse_url_content(App $a)
                                $hdrs[$k] = $v;
                        }
                }
+               $type = null;
                if (array_key_exists('Content-Type', $hdrs)) {
                        $type = $hdrs['Content-Type'];
                }
index ff0139f28f9d3b405f0b148ccf694b8ba03f0171..5ea75727a1152d6d3f12943dcb7b5b9eb684fcbc 100644 (file)
@@ -202,11 +202,7 @@ function ping_init(App $a)
                $mail_count = count($mails);
 
                if (intval(Config::get('config', 'register_policy')) === REGISTER_APPROVE && is_site_admin()) {
-                       $regs = q(
-                               "SELECT `contact`.`name`, `contact`.`url`, `contact`.`micro`, `register`.`created`
-                               FROM `contact` RIGHT JOIN `register` ON `register`.`uid` = `contact`.`uid`
-                               WHERE `contact`.`self` = 1"
-                       );
+                       $regs = Friendica\Model\Register::getPending();
 
                        if (DBA::isResult($regs)) {
                                $register_count = count($regs);
index 1720e0ff3a385df8a8c1b99bd3013a11be466697..41d39f4158204b09792e084f9c732d790bd3066a 100644 (file)
@@ -12,10 +12,8 @@ use Friendica\Core\L10n;
 use Friendica\Core\PConfig;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
-use Friendica\Database\DBA;
-use Friendica\Model\User;
+use Friendica\Model;
 use Friendica\Module\Tos;
-use Friendica\Util\DateTimeFormat;
 
 require_once 'include/enotify.php';
 
@@ -68,7 +66,7 @@ function register_post(App $a)
        $arr['language'] = L10n::getBrowserLanguage();
 
        try {
-               $result = User::create($arr);
+               $result = Model\User::create($arr);
        } catch (Exception $e) {
                notice($e->getMessage());
                return;
@@ -77,7 +75,7 @@ function register_post(App $a)
        $user = $result['user'];
 
        if ($netpublish && intval(Config::get('config', 'register_policy')) !== REGISTER_APPROVE) {
-               $url = System::baseUrl() . '/profile/' . $user['nickname'];
+               $url = $a->getBaseUrl() . '/profile/' . $user['nickname'];
                Worker::add(PRIORITY_LOW, "Directory", $url);
        }
 
@@ -87,18 +85,22 @@ function register_post(App $a)
 
        if (intval(Config::get('config', 'register_policy')) === REGISTER_OPEN) {
                if ($using_invites && $invite_id) {
-                       q("delete * from register where hash = '%s' limit 1", DBA::escape($invite_id));
+                       Model\Register::deleteByHash($invite_id);
                        PConfig::set($user['uid'], 'system', 'invites_remaining', $num_invites);
                }
 
                // Only send a password mail when the password wasn't manually provided
                if (!x($_POST, 'password1') || !x($_POST, 'confirm')) {
-                       $res = User::sendRegisterOpenEmail(
-                                       $user['email'], Config::get('config', 'sitename'), System::baseUrl(), $user['username'], $result['password'], $user);
+                       $res = Model\User::sendRegisterOpenEmail(
+                               $user,
+                               Config::get('config', 'sitename'),
+                               $a->getBaseUrl(),
+                               $result['password']
+                       );
 
                        if ($res) {
                                info(L10n::t('Registration successful. Please check your email for further instructions.') . EOL);
-                               goaway(System::baseUrl());
+                               goaway();
                        } else {
                                notice(
                                        L10n::t('Failed to send email message. Here your accout details:<br> login: %s<br> password: %s<br><br>You can change your password after login.',
@@ -109,27 +111,19 @@ function register_post(App $a)
                        }
                } else {
                        info(L10n::t('Registration successful.') . EOL);
-                       goaway(System::baseUrl());
+                       goaway();
                }
        } elseif (intval(Config::get('config', 'register_policy')) === REGISTER_APPROVE) {
                if (!strlen(Config::get('config', 'admin_email'))) {
                        notice(L10n::t('Your registration can not be processed.') . EOL);
-                       goaway(System::baseUrl());
+                       goaway();
                }
 
-               $hash = random_string();
-               $r = q("INSERT INTO `register` ( `hash`, `created`, `uid`, `password`, `language`, `note` ) VALUES ( '%s', '%s', %d, '%s', '%s', '%s' ) ",
-                       DBA::escape($hash),
-                       DBA::escape(DateTimeFormat::utcNow()),
-                       intval($user['uid']),
-                       DBA::escape($result['password']),
-                       DBA::escape(Config::get('system', 'language')),
-                       DBA::escape($_POST['permonlybox'])
-               );
+               Model\Register::createForApproval($user['uid'], Config::get('system', 'language'), $_POST['permonlybox']);
 
                // invite system
                if ($using_invites && $invite_id) {
-                       q("DELETE * FROM `register` WHERE `hash` = '%s' LIMIT 1", DBA::escape($invite_id));
+                       Model\Register::deleteByHash($invite_id);
                        PConfig::set($user['uid'], 'system', 'invites_remaining', $num_invites);
                }
 
@@ -147,9 +141,9 @@ function register_post(App $a)
                                'source_name'  => $user['username'],
                                'source_mail'  => $user['email'],
                                'source_nick'  => $user['nickname'],
-                               'source_link'  => System::baseUrl() . "/admin/users/",
-                               'link'         => System::baseUrl() . "/admin/users/",
-                               'source_photo' => System::baseUrl() . "/photo/avatar/" . $user['uid'] . ".jpg",
+                               'source_link'  => $a->getBaseUrl() . "/admin/users/",
+                               'link'         => $a->getBaseUrl() . "/admin/users/",
+                               'source_photo' => $a->getBaseUrl() . "/photo/avatar/" . $user['uid'] . ".jpg",
                                'to_email'     => $admin['email'],
                                'uid'          => $admin['uid'],
                                'language'     => $admin['language'] ? $admin['language'] : 'en',
@@ -157,11 +151,15 @@ function register_post(App $a)
                        ]);
                }
                // send notification to the user, that the registration is pending
-               User::sendRegisterPendingEmail(
-                       $user['email'], Config::get('config', 'sitename'), $user['username']);
+               Model\User::sendRegisterPendingEmail(
+                       $user,
+                       Config::get('config', 'sitename'),
+                       $a->getBaseURL(),
+                       $result['password']
+               );
 
                info(L10n::t('Your registration is pending approval by the site owner.') . EOL);
-               goaway(System::baseUrl());
+               goaway();
        }
 
        return;
index 11d8eee412eadd013fb2b0197b825803db8baa2c..3f6f0e04e3253e6073f686548e16450b3374d225 100644 (file)
@@ -9,6 +9,7 @@ use Friendica\Core\L10n;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
+use Friendica\Model\Register;
 use Friendica\Model\User;
 use Friendica\Module\Login;
 
@@ -18,51 +19,35 @@ function user_allow($hash)
 {
        $a = get_app();
 
-       $register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1",
-               DBA::escape($hash)
-       );
-
-
+       $register = Register::getByHash($hash);
        if (!DBA::isResult($register)) {
                return false;
        }
 
-       $user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
-               intval($register[0]['uid'])
-       );
-
+       $user = User::getById($register['uid']);
        if (!DBA::isResult($user)) {
-               killme();
+               exit();
        }
 
-       $r = q("DELETE FROM `register` WHERE `hash` = '%s'",
-               DBA::escape($register[0]['hash'])
-       );
+       Register::deleteByHash($hash);
 
+       DBA::update('user', ['blocked' => false, 'verified' => true], ['uid' => $register['uid']]);
 
-       $r = q("UPDATE `user` SET `blocked` = 0, `verified` = 1 WHERE `uid` = %d",
-               intval($register[0]['uid'])
-       );
+       $profile = DBA::selectFirst('profile', ['net-publish'], ['uid' => $register['uid'], 'is-default' => true]);
 
-       $r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `is-default` = 1",
-               intval($user[0]['uid'])
-       );
-       if (DBA::isResult($r) && $r[0]['net-publish']) {
-               $url = System::baseUrl() . '/profile/' . $user[0]['nickname'];
-               if ($url && strlen(Config::get('system', 'directory'))) {
-                       Worker::add(PRIORITY_LOW, "Directory", $url);
-               }
+       if (DBA::isResult($profile) && $profile['net-publish'] && Config::get('system', 'directory')) {
+               $url = System::baseUrl() . '/profile/' . $user['nickname'];
+               Worker::add(PRIORITY_LOW, "Directory", $url);
        }
 
-       L10n::pushLang($register[0]['language']);
+       L10n::pushLang($register['language']);
 
        $res = User::sendRegisterOpenEmail(
-               $user[0]['email'],
+               $user,
                Config::get('config', 'sitename'),
-               System::baseUrl(),
-               $user[0]['username'],
-               $register[0]['password'],
-               $user[0]);
+               $a->getBaseUrl(),
+               defaults($register, 'password', 'Sent in a previous email')
+       );
 
        L10n::popLang();
 
@@ -77,22 +62,21 @@ function user_allow($hash)
 // allowed to have friends on this system
 function user_deny($hash)
 {
-       $register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1",
-               DBA::escape($hash)
-       );
-
+       $register = Register::getByHash($hash);
        if (!DBA::isResult($register)) {
                return false;
        }
 
-       $user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
-               intval($register[0]['uid'])
-       );
+       $user = User::getById($register['uid']);
+       if (!DBA::isResult($user)) {
+               exit();
+       }
+
+       DBA::delete('user', ['uid' => $register['uid']]);
 
-       DBA::delete('user', ['uid' => $register[0]['uid']]);
-       DBA::delete('register', ['hash' => $register[0]['hash']]);
+       Register::deleteByHash($register['hash']);
 
-       notice(L10n::t('Registration revoked for %s', $user[0]['username']) . EOL);
+       notice(L10n::t('Registration revoked for %s', $user['username']) . EOL);
        return true;
 }
 
@@ -100,17 +84,16 @@ function regmod_content(App $a)
 {
        if (!local_user()) {
                info(L10n::t('Please login.') . EOL);
-               $o = '<br /><br />' . Login::form($a->query_string, intval(Config::get('config', 'register_policy')) === REGISTER_CLOSED ? 0 : 1);
-               return $o;
+               return Login::form($a->query_string, intval(Config::get('config', 'register_policy')) === REGISTER_CLOSED ? 0 : 1);
        }
 
-       if ((!is_site_admin()) || (x($_SESSION, 'submanage') && intval($_SESSION['submanage']))) {
+       if (!is_site_admin() || !empty($_SESSION['submanage'])) {
                notice(L10n::t('Permission denied.') . EOL);
                return '';
        }
 
        if ($a->argc != 3) {
-               killme();
+               exit();
        }
 
        $cmd = $a->argv[1];
@@ -118,13 +101,11 @@ function regmod_content(App $a)
 
        if ($cmd === 'deny') {
                user_deny($hash);
-               goaway(System::baseUrl() . "/admin/users/");
-               killme();
+               goaway('admin/users/');
        }
 
        if ($cmd === 'allow') {
                user_allow($hash);
-               goaway(System::baseUrl() . "/admin/users/");
-               killme();
+               goaway('admin/users/');
        }
 }
index 9b0e206904bad703e608d2a460d993a72f39909c..6a058608e7a0dd5c2808c580f3262fe48cb5d9aa 100644 (file)
@@ -59,7 +59,7 @@ function unfollow_post()
                $return_path = 'contacts';
        } else {
                DBA::update('contact', ['rel' => Contact::FOLLOWER], ['id' => $contact['id']]);
-               $return_path = 'contacts/' . $contact['id'];
+               $return_path = 'contact/' . $contact['id'];
        }
 
        info(L10n::t('Contact unfollowed'));
@@ -94,7 +94,7 @@ function unfollow_content(App $a)
 
        if (!in_array($contact['network'], Protocol::NATIVE_SUPPORT)) {
                notice(L10n::t('Unfollowing is currently not supported by your network.'));
-               goaway('contacts/' . $contact['id']);
+               goaway('contact/' . $contact['id']);
                // NOTREACHED
        }
 
index c903ee6945790fcd96e85c476af168c4ff124c91..be2054067b25b68a9a898e9f732a524390cd11db 100644 (file)
@@ -859,187 +859,140 @@ class BBCode extends BaseObject
        }
 
        /**
-        * Processes [share] tags
+        * This function converts a [share] block to text according to a provided callback function whose signature is:
         *
-        * Note: Can produce a [bookmark] tag in the output
+        * function(array $attributes, array $author_contact, string $content, boolean $is_quote_share): string
         *
-        * @brief Processes [share] tags
-        * @param array    $share      preg_match_callback result array
-        * @param bool|int $simplehtml
-        * @return string
+        * Where:
+        * - $attributes is an array of attributes of the [share] block itself. Missing keys will be completed by the contact
+        * data lookup
+        * - $author_contact is a contact record array
+        * - $content is the inner content of the [share] block
+        * - $is_quote_share indicates whether there's any content before the [share] block
+        * - Return value is the string that should replace the [share] block in the provided text
+        *
+        * This function is intended to be used by addon connector to format a share block like the target network is expecting it.
+        *
+        * @param  string   $text     A BBCode string
+        * @param  callable $callback
+        * @return string The BBCode string with all [share] blocks replaced
         */
-       private static function convertShare($share, $simplehtml)
+       public static function convertShare($text, callable $callback)
        {
-               $attributes = $share[2];
-
-               $author = "";
-               preg_match("/author='(.*?)'/ism", $attributes, $matches);
-               if (x($matches, 1)) {
-                       $author = html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
-               }
-
-               preg_match('/author="(.*?)"/ism', $attributes, $matches);
-               if (x($matches, 1)) {
-                       $author = $matches[1];
-               }
-
-               $profile = "";
-               preg_match("/profile='(.*?)'/ism", $attributes, $matches);
-               if (x($matches, 1)) {
-                       $profile = $matches[1];
-               }
-
-               preg_match('/profile="(.*?)"/ism', $attributes, $matches);
-               if (x($matches, 1)) {
-                       $profile = $matches[1];
-               }
-
-               $avatar = "";
-               preg_match("/avatar='(.*?)'/ism", $attributes, $matches);
-               if (x($matches, 1)) {
-                       $avatar = $matches[1];
-               }
-
-               preg_match('/avatar="(.*?)"/ism', $attributes, $matches);
-               if (x($matches, 1)) {
-                       $avatar = $matches[1];
-               }
-
-               $link = "";
-               preg_match("/link='(.*?)'/ism", $attributes, $matches);
-               if (x($matches, 1)) {
-                       $link = $matches[1];
-               }
-
-               preg_match('/link="(.*?)"/ism', $attributes, $matches);
-               if (x($matches, 1)) {
-                       $link = $matches[1];
-               }
-
-               $posted = "";
-
-               preg_match("/posted='(.*?)'/ism", $attributes, $matches);
-               if (x($matches, 1)) {
-                       $posted = $matches[1];
-               }
-
-               preg_match('/posted="(.*?)"/ism', $attributes, $matches);
-               if (x($matches, 1)) {
-                       $posted = $matches[1];
-               }
+               $return = preg_replace_callback(
+                       "/(.*?)\[share(.*?)\](.*?)\[\/share\]/ism",
+                       function ($match) use ($callback) {
+                               $attribute_string = $match[2];
+
+                               $attributes = [];
+                               foreach(['author', 'profile', 'avatar', 'link', 'posted'] as $field) {
+                                       preg_match("/$field=(['\"])(.+?)\\1/ism", $attribute_string, $matches);
+                                       $attributes[$field] = html_entity_decode(defaults($matches, 2, ''), ENT_QUOTES, 'UTF-8');
+                               }
 
-               // We only call this so that a previously unknown contact can be added.
-               // This is important for the function "Model\Contact::getDetailsByURL()".
-               // This function then can fetch an entry from the contact table.
-               Contact::getIdForURL($profile, 0, true);
+                               // We only call this so that a previously unknown contact can be added.
+                               // This is important for the function "Model\Contact::getDetailsByURL()".
+                               // This function then can fetch an entry from the contact table.
+                               Contact::getIdForURL($attributes['profile'], 0, true);
 
-               $data = Contact::getDetailsByURL($profile);
+                               $author_contact = Contact::getDetailsByURL($attributes['profile']);
+                               $author_contact['addr'] = defaults($author_contact, 'addr' , Protocol::getAddrFromProfileUrl($attributes['profile']));
 
-               if (x($data, "name") && x($data, "addr")) {
-                       $userid_compact = $data["name"] . " (" . $data["addr"] . ")";
-               } else {
-                       $userid_compact = Protocol::getAddrFromProfileUrl($profile, $author);
-               }
+                               $attributes['author']   = defaults($author_contact, 'name' , $attributes['author']);
+                               $attributes['avatar']   = defaults($author_contact, 'micro', $attributes['avatar']);
+                               $attributes['profile']  = defaults($author_contact, 'url'  , $attributes['profile']);
 
-               if (x($data, "addr")) {
-                       $userid = $data["addr"];
-               } else {
-                       $userid = Protocol::formatMention($profile, $author);
-               }
+                               if ($attributes['avatar']) {
+                                       $attributes['avatar'] = ProxyUtils::proxifyUrl($attributes['avatar'], false, ProxyUtils::SIZE_THUMB);
+                               }
 
-               if (x($data, "name")) {
-                       $author = $data["name"];
-               }
+                               return $match[1] . $callback($attributes, $author_contact, $match[3], trim($match[1]) != '');
+                       },
+                       $text
+               );
 
-               if (x($data, "micro")) {
-                       $avatar = $data["micro"];
-               }
+               return $return;
+       }
 
-               $preshare = trim($share[1]);
-               if ($preshare != "") {
-                       $preshare .= "<br />";
-               }
+       /**
+        * Default [share] tag conversion callback
+        *
+        * Note: Can produce a [bookmark] tag in the output
+        *
+        * @see BBCode::convertShare()
+        * @param array   $attributes     [share] block attribute values
+        * @param array   $author_contact Contact row of the shared author
+        * @param string  $content        Inner content of the [share] block
+        * @param boolean $is_quote_share Whether there is content before the [share] block
+        * @param integer $simplehtml     Mysterious integer value depending on the target network/formatting style
+        * @return string
+        */
+       private static function convertShareCallback(array $attributes, array $author_contact, $content, $is_quote_share, $simplehtml)
+       {
+               $mention = Protocol::formatMention($attributes['profile'], $attributes['author']);
 
                switch ($simplehtml) {
                        case 1:
-                               $text = $preshare . html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8') . ' <a href="' . $profile . '">' . $userid . "</a>: <br />»" . $share[3] . "«";
+                               $text = ($is_quote_share? '<br />' : '') . '<p>' . html_entity_decode('&#x2672; ', ENT_QUOTES, 'UTF-8') . ' <a href="' . $attributes['profile'] . '">' . $mention . '</a>: </p>' . "\n" . '«' . $content . '»';
                                break;
                        case 2:
-                               $text = $preshare . html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8') . ' ' . $userid_compact . ": <br />" . $share[3];
+                               $text = ($is_quote_share? '<br />' : '') . '<p>' . html_entity_decode('&#x2672; ', ENT_QUOTES, 'UTF-8') . ' ' . $author_contact['addr'] . ': </p>' . "\n" . $content;
                                break;
                        case 3: // Diaspora
-                               $headline = '<b>' . html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8') . $userid . ':</b><br />';
-
-                               $text = trim($share[1]);
-
-                               if ($text != "") {
-                                       $text .= "<hr />";
-                               }
+                               $headline = '<p><b>' . html_entity_decode('&#x2672; ', ENT_QUOTES, 'UTF-8') . $mention . ':</b></p>' . "\n";
 
-                               if (stripos(normalise_link($link), 'http://twitter.com/') === 0) {
-                                       $text .= '<br /><a href="' . $link . '">' . $link . '</a>';
+                               if (stripos(normalise_link($attributes['link']), 'http://twitter.com/') === 0) {
+                                       $text = ($is_quote_share? '<hr />' : '') . '<p><a href="' . $attributes['link'] . '">' . $attributes['link'] . '</a></p>' . "\n";
                                } else {
-                                       $text .= $headline . '<blockquote>' . trim($share[3]) . "</blockquote><br />";
+                                       $text = ($is_quote_share? '<hr />' : '') . $headline . '<blockquote>' . trim($content) . '</blockquote>' . "\n";
 
-                                       if ($link != "") {
-                                               $text .= '<br /><a href="' . $link . '">[l]</a>';
+                                       if ($attributes['link'] != '') {
+                                               $text .= '<p><a href="' . $attributes['link'] . '">[l]</a></p>' . "\n";
                                        }
                                }
 
                                break;
                        case 4:
-                               $headline = '<br /><b>' . html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8');
-                               $headline .= L10n::t('<a href="%1$s" target="_blank">%2$s</a> %3$s', $link, $userid, $posted);
-                               $headline .= ":</b><br />";
+                               $headline = '<p><b>' . html_entity_decode('&#x2672; ', ENT_QUOTES, 'UTF-8');
+                               $headline .= L10n::t('<a href="%1$s" target="_blank">%2$s</a> %3$s', $attributes['link'], $mention, $attributes['posted']);
+                               $headline .= ':</b></p>' . "\n";
 
-                               $text = trim($share[1]);
-
-                               if ($text != "") {
-                                       $text .= "<hr />";
-                               }
-
-                               $text .= $headline . '<blockquote class="shared_content">' . trim($share[3]) . "</blockquote><br />";
+                               $text = ($is_quote_share? '<hr />' : '') . $headline . '<blockquote class="shared_content">' . trim($content) . '</blockquote>' . "\n";
 
                                break;
                        case 5:
-                               $text = $preshare . html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8') . ' ' . $userid_compact . ": <br />" . $share[3];
+                               $text = ($is_quote_share? '<br />' : '') . '<p>' . html_entity_decode('&#x2672; ', ENT_QUOTES, 'UTF-8') . ' ' . $author_contact['addr'] . ': </p>' . "\n" . $content;
                                break;
                        case 7: // statusnet/GNU Social
-                               $text = $preshare . html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8') . " @" . $userid_compact . ": " . $share[3];
-                               break;
-                       case 8: // twitter
-                               $text = $preshare . "RT @" . $userid_compact . ": " . $share[3];
+                               $text = ($is_quote_share? '<br />' : '') . '<p>' . html_entity_decode('&#x2672; ', ENT_QUOTES, 'UTF-8') . ' @' . $author_contact['addr'] . ': ' . $content . '</p>' . "\n";
                                break;
                        case 9: // Google+
-                               $text = $preshare . html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8') . ' ' . $userid_compact . ": <br />" . $share[3];
+                               $text = ($is_quote_share? '<br />' : '') . '<p>' . html_entity_decode('&#x2672; ', ENT_QUOTES, 'UTF-8') . ' ' . $author_contact['addr'] . ': </p>' . "\n";
+                               $text .= '<p>' . $content . '</p>' . "\n";
 
-                               if ($link != "") {
-                                       $text .= "<br /><br />" . $link;
+                               if ($attributes['link'] != '') {
+                                       $text .= '<p>' . $attributes['link'] . '</p>';
                                }
                                break;
                        default:
                                // Transforms quoted tweets in rich attachments to avoid nested tweets
-                               if (stripos(normalise_link($link), 'http://twitter.com/') === 0 && OEmbed::isAllowedURL($link)) {
+                               if (stripos(normalise_link($attributes['link']), 'http://twitter.com/') === 0 && OEmbed::isAllowedURL($attributes['link'])) {
                                        try {
-                                               $oembed = OEmbed::getHTML($link, $preshare);
+                                               $text = ($is_quote_share? '<br />' : '') . OEmbed::getHTML($attributes['link']);
                                        } catch (Exception $e) {
-                                               $oembed = sprintf('[bookmark=%s]%s[/bookmark]', $link, $preshare);
+                                               $text = ($is_quote_share? '<br />' : '') . sprintf('[bookmark=%s]%s[/bookmark]', $attributes['link'], $content);
                                        }
-
-                                       $text = $preshare . $oembed;
                                } else {
-                                       $text = trim($share[1]) . "\n";
-
-                                       $avatar = ProxyUtils::proxifyUrl($avatar, false, ProxyUtils::SIZE_THUMB);
+                                       $text = ($is_quote_share? "\n" : '');
 
                                        $tpl = get_markup_template('shared_content.tpl');
                                        $text .= replace_macros($tpl, [
-                                               '$profile' => $profile,
-                                               '$avatar' => $avatar,
-                                               '$author' => $author,
-                                               '$link' => $link,
-                                               '$posted' => $posted,
-                                               '$content' => trim($share[3])
+                                               '$profile' => $attributes['profile'],
+                                               '$avatar'  => $attributes['avatar'],
+                                               '$author'  => $attributes['author'],
+                                               '$link'    => $attributes['link'],
+                                               '$posted'  => $attributes['posted'],
+                                               '$content' => trim($content)
                                        ]);
                                }
                                break;
@@ -1366,7 +1319,7 @@ class BBCode extends BaseObject
 
                // Handle Diaspora posts
                $text = preg_replace_callback(
-                       "&\[url=/posts/([^\[\]]*)\](.*)\[\/url\]&Usi",
+                       "&\[url=/?posts/([^\[\]]*)\](.*)\[\/url\]&Usi",
                        function ($match) {
                                return "[url=" . System::baseUrl() . "/display/" . $match[1] . "]" . $match[2] . "[/url]";
                        }, $text
@@ -1621,10 +1574,12 @@ class BBCode extends BaseObject
                $text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '<img src="$1" alt="' . L10n::t('Image/photo') . '" />', $text);
 
                // Shared content
-               $text = preg_replace_callback("/(.*?)\[share(.*?)\](.*?)\[\/share\]/ism",
-                       function ($match) use ($simple_html) {
-                               return self::convertShare($match, $simple_html);
-                       }, $text);
+               $text = self::convertShare(
+                       $text,
+                       function (array $attributes, array $author_contact, $content, $is_quote_share) use ($simple_html) {
+                               return self::convertShareCallback($attributes, $author_contact, $content, $is_quote_share, $simple_html);
+                       }
+               );
 
                $text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism", '<br/><img src="' .System::baseUrl() . '/images/lock_icon.gif" alt="' . L10n::t('Encrypted content') . '" title="' . L10n::t('Encrypted content') . '" /><br />', $text);
                $text = preg_replace("/\[crypt(.*?)\](.*?)\[\/crypt\]/ism", '<br/><img src="' .System::baseUrl() . '/images/lock_icon.gif" alt="' . L10n::t('Encrypted content') . '" title="' . '$1' . ' ' . L10n::t('Encrypted content') . '" /><br />', $text);
index d41250a68643eb2db0ff91cff4bf7f996b9c4d2c..949e2350c3be85ceb72f93d0ad756cb8d2936b84 100644 (file)
@@ -108,6 +108,13 @@ class Protocol
                        }
                }
 
+               // Mastodon, Pleroma
+               if (preg_match('=https?://(.+?)/users/(.+)=ism', $profile_url, $matches)
+                       || preg_match('=https?://(.+?)/@(.+)=ism', $profile_url, $matches)
+               ) {
+                       return self::ACTIVITYPUB;
+               }
+
                // pumpio (http://host.name/user)
                if (preg_match('=https?://([\.\w]+)/([\.\w]+)$=ism', $profile_url, $matches)) {
                        return self::PUMPIO;
index c33fa2152fb5aebfd5b9ad84ac04ed4dd3d57776..8fd117e5d2c56f742b399dcf93d8ea2988218317 100644 (file)
@@ -821,7 +821,7 @@ class DBA
         * @param array $param parameter array
         * @param bool $on_duplicate_update Do an update on a duplicate entry
         *
-        * @return boolean was the insert successfull?
+        * @return boolean was the insert successful?
         */
        public static function insert($table, $param, $on_duplicate_update = false) {
 
index 4588bb7129d3e4f2f4ad8936e177f5d133422f29..472875a80bc1a05088b1db840d1ac6518f9d654e 100644 (file)
@@ -1021,10 +1021,11 @@ class Contact extends BaseObject
         * @param integer $uid       The user id for the contact (0 = public contact)
         * @param boolean $no_update Don't update the contact
         * @param array   $default   Default value for creating the contact when every else fails
+        * @param boolean $in_loop   Internally used variable to prevent an endless loop
         *
         * @return integer Contact ID
         */
-       public static function getIdForURL($url, $uid = 0, $no_update = false, $default = [])
+       public static function getIdForURL($url, $uid = 0, $no_update = false, $default = [], $in_loop = false)
        {
                logger("Get contact data for url " . $url . " and user " . $uid . " - " . System::callstack(), LOGGER_DEBUG);
 
@@ -1138,8 +1139,8 @@ class Contact extends BaseObject
                        }
                }
 
-               if (!$contact_id && ($data["alias"] != '') && ($data["alias"] != $url)) {
-                       $contact_id = self::getIdForURL($data["alias"], $uid, true);
+               if (!$contact_id && ($data["alias"] != '') && ($data["alias"] != $url) && !$in_loop) {
+                       $contact_id = self::getIdForURL($data["alias"], $uid, true, $default, true);
                }
 
                $url = $data["url"];
index be1eaf2295582a7e1bb1e0777cd7410a63e56f83..25075dcfbe41cbdab375d0c964c74c62fddd9d3f 100644 (file)
@@ -26,6 +26,11 @@ class Conversation
        const PARCEL_TWITTER            = 67;
        const PARCEL_UNKNOWN            = 255;
 
+       public static function getByItemUri($item_uri)
+       {
+               return DBA::selectFirst('conversation', [], ['item-uri' => $item_uri]);
+       }
+
        /**
         * @brief Store the conversation data
         *
index dd513d0008fe129766ae08d2b93b671f1106e469..1c0b11db4aae80c6b3db9c5e2782b08940b96e46 100644 (file)
@@ -81,7 +81,7 @@ class Item extends BaseObject
        // All fields in the item table
        const ITEM_FIELDLIST = ['id', 'uid', 'parent', 'uri', 'parent-uri', 'thr-parent', 'guid',
                        'contact-id', 'type', 'wall', 'gravity', 'extid', 'icid', 'iaid', 'psid',
-                       'uri-hash', 'created', 'edited', 'commented', 'received', 'changed', 'verb',
+                       'created', 'edited', 'commented', 'received', 'changed', 'verb',
                        'postopts', 'plink', 'resource-id', 'event-id', 'tag', 'attach', 'inform',
                        'file', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'post-type',
                        'private', 'pubmail', 'moderated', 'visible', 'starred', 'bookmark',
@@ -381,7 +381,7 @@ class Item extends BaseObject
                        $usermode = true;
                }
 
-               $fields = self::fieldlist($selected, $usermode);
+               $fields = self::fieldlist($usermode);
 
                $select_fields = self::constructSelectFields($fields, $selected);
 
@@ -488,7 +488,7 @@ class Item extends BaseObject
                        $usermode = true;
                }
 
-               $fields = self::fieldlist($selected, $usermode);
+               $fields = self::fieldlist($usermode);
 
                $fields['thread'] = ['mention', 'ignored', 'iid'];
 
@@ -524,13 +524,13 @@ class Item extends BaseObject
         *
         * @return array field list
         */
-       private static function fieldlist($selected, $usermode)
+       private static function fieldlist($usermode)
        {
                $fields = [];
 
                $fields['item'] = ['id', 'uid', 'parent', 'uri', 'parent-uri', 'thr-parent', 'guid',
                        'contact-id', 'owner-id', 'author-id', 'type', 'wall', 'gravity', 'extid',
-                       'created', 'edited', 'commented', 'received', 'changed', 'psid', 'uri-hash',
+                       'created', 'edited', 'commented', 'received', 'changed', 'psid',
                        'resource-id', 'event-id', 'tag', 'attach', 'post-type', 'file',
                        'private', 'pubmail', 'moderated', 'visible', 'starred', 'bookmark',
                        'unseen', 'deleted', 'origin', 'forum_mode', 'mention', 'global',
@@ -666,11 +666,11 @@ class Item extends BaseObject
                }
 
                if (strpos($sql_commands, "`item-activity`.") !== false) {
-                       $joins .= " LEFT JOIN `item-activity` ON `item-activity`.`id` = `item`.`iaid`";
+                       $joins .= " LEFT JOIN `item-activity` ON `item-activity`.`uri-id` = `item`.`uri-id`";
                }
 
                if (strpos($sql_commands, "`item-content`.") !== false) {
-                       $joins .= " LEFT JOIN `item-content` ON `item-content`.`id` = `item`.`icid`";
+                       $joins .= " LEFT JOIN `item-content` ON `item-content`.`uri-id` = `item`.`uri-id`";
                }
 
                if (strpos($sql_commands, "`item-delivery-data`.") !== false) {
@@ -766,19 +766,6 @@ class Item extends BaseObject
                return $query;
        }
 
-       /**
-        * @brief Generate a server unique item hash for linking between the item tables
-        *
-        * @param string $uri     Item URI
-        * @param date   $created Item creation date
-        *
-        * @return string the item hash
-        */
-       private static function itemHash($uri, $created)
-       {
-               return round(strtotime($created) / 100) . hash('ripemd128', $uri);
-       }
-
        /**
         * @brief Update existing item entries
         *
@@ -804,7 +791,7 @@ class Item extends BaseObject
                // We cannot simply expand the condition to check for origin entries
                // The condition needn't to be a simple array but could be a complex condition.
                // And we have to execute this query before the update to ensure to fetch the same data.
-               $items = DBA::select('item', ['id', 'origin', 'uri', 'created', 'uri-hash', 'iaid', 'icid', 'tag', 'file'], $condition);
+               $items = DBA::select('item', ['id', 'origin', 'uri', 'uri-id', 'iaid', 'icid', 'tag', 'file'], $condition);
 
                $content_fields = [];
                foreach (array_merge(self::CONTENT_FIELDLIST, self::MIXED_CONTENT_FIELDLIST) as $field) {
@@ -859,34 +846,11 @@ class Item extends BaseObject
                $rows = DBA::affectedRows();
 
                while ($item = DBA::fetch($items)) {
-
-                       // This part here can safely be removed when the legacy fields in the item had been removed
-                       if (empty($item['uri-hash']) && !empty($item['uri']) && !empty($item['created'])) {
-
-                               // Fetch the uri-hash from an existing item entry if there is one
-                               $item_condition = ["`uri` = ? AND `uri-hash` != ''", $item['uri']];
-                               $existing = DBA::selectfirst('item', ['uri-hash'], $item_condition);
-                               if (DBA::isResult($existing)) {
-                                       $item['uri-hash'] = $existing['uri-hash'];
-                               } else {
-                                       $item['uri-hash'] = self::itemHash($item['uri'], $item['created']);
-                               }
-
-                               DBA::update('item', ['uri-hash' => $item['uri-hash']], ['id' => $item['id']]);
-                               DBA::update('item-activity', ['uri-hash' => $item['uri-hash']], ["`uri` = ? AND `uri-hash` = ''", $item['uri']]);
-                               DBA::update('item-content', ['uri-plink-hash' => $item['uri-hash']], ["`uri` = ? AND `uri-plink-hash` = ''", $item['uri']]);
-                       }
-
                        if (!empty($item['iaid']) || (!empty($content_fields['verb']) && (self::activityToIndex($content_fields['verb']) >= 0))) {
-                               if (!empty($item['iaid'])) {
-                                       $update_condition = ['id' => $item['iaid']];
-                               } else {
-                                       $update_condition = ['uri-hash' => $item['uri-hash']];
-                               }
-                               self::updateActivity($content_fields, $update_condition);
+                               self::updateActivity($content_fields, ['uri-id' => $item['uri-id']]);
 
                                if (empty($item['iaid'])) {
-                                       $item_activity = DBA::selectFirst('item-activity', ['id'], ['uri-hash' => $item['uri-hash']]);
+                                       $item_activity = DBA::selectFirst('item-activity', ['id'], ['uri-id' => $item['uri-id']]);
                                        if (DBA::isResult($item_activity)) {
                                                $item_fields = ['iaid' => $item_activity['id'], 'icid' => null];
                                                foreach (self::MIXED_CONTENT_FIELDLIST as $field) {
@@ -910,15 +874,10 @@ class Item extends BaseObject
                                        }
                                }
                        } else {
-                               if (!empty($item['icid'])) {
-                                       $update_condition = ['id' => $item['icid']];
-                               } else {
-                                       $update_condition = ['uri-plink-hash' => $item['uri-hash']];
-                               }
-                               self::updateContent($content_fields, $update_condition);
+                               self::updateContent($content_fields, ['uri-id' => $item['uri-id']]);
 
                                if (empty($item['icid'])) {
-                                       $item_content = DBA::selectFirst('item-content', [], ['uri-plink-hash' => $item['uri-hash']]);
+                                       $item_content = DBA::selectFirst('item-content', [], ['uri-id' => $item['uri-id']]);
                                        if (DBA::isResult($item_content)) {
                                                $item_fields = ['icid' => $item_content['id']];
                                                // Clear all fields in the item table that have a content in the item-content table
@@ -1381,13 +1340,6 @@ class Item extends BaseObject
                        }
                }
 
-               // Ensure to always have the same creation date.
-               $existing = self::selectfirst(['created', 'uri-hash'], ['uri' => $item['uri']]);
-               if (DBA::isResult($existing)) {
-                       $item['created'] = $existing['created'];
-                       $item['uri-hash'] = $existing['uri-hash'];
-               }
-
                $item['wall']          = intval(defaults($item, 'wall', 0));
                $item['extid']         = trim(defaults($item, 'extid', ''));
                $item['author-name']   = trim(defaults($item, 'author-name', ''));
@@ -1430,9 +1382,6 @@ class Item extends BaseObject
                $item['inform']        = trim(defaults($item, 'inform', ''));
                $item['file']          = trim(defaults($item, 'file', ''));
 
-               // Unique identifier to be linked against item-activities and item-content
-               $item['uri-hash']      = defaults($item, 'uri-hash', self::itemHash($item['uri'], $item['created']));
-
                // When there is no content then we don't post it
                if ($item['body'].$item['title'] == '') {
                        logger('No body, no title.');
@@ -1928,8 +1877,7 @@ class Item extends BaseObject
                        return false;
                }
 
-               $fields = ['uri' => $item['uri'], 'activity' => $activity_index,
-                       'uri-hash' => $item['uri-hash'], 'uri-id' => $item['uri-id']];
+               $fields = ['activity' => $activity_index, 'uri-hash' => (string)$item['uri-id'], 'uri-id' => $item['uri-id']];
 
                // We just remove everything that is content
                foreach (array_merge(self::CONTENT_FIELDLIST, self::MIXED_CONTENT_FIELDLIST) as $field) {
@@ -1943,7 +1891,7 @@ class Item extends BaseObject
                }
 
                // Do we already have this content?
-               $item_activity = DBA::selectFirst('item-activity', ['id'], ['uri-hash' => $item['uri-hash']]);
+               $item_activity = DBA::selectFirst('item-activity', ['id'], ['uri-id' => $item['uri-id']]);
                if (DBA::isResult($item_activity)) {
                        $item['iaid'] = $item_activity['id'];
                        logger('Fetched activity for URI ' . $item['uri'] . ' (' . $item['iaid'] . ')');
@@ -1969,8 +1917,7 @@ class Item extends BaseObject
         */
        private static function insertContent(&$item)
        {
-               $fields = ['uri' => $item['uri'], 'uri-plink-hash' => $item['uri-hash'],
-                       'uri-id' => $item['uri-id']];
+               $fields = ['uri-plink-hash' => (string)$item['uri-id'], 'uri-id' => $item['uri-id']];
 
                foreach (array_merge(self::CONTENT_FIELDLIST, self::MIXED_CONTENT_FIELDLIST) as $field) {
                        if (isset($item[$field])) {
@@ -1986,7 +1933,7 @@ class Item extends BaseObject
                }
 
                // Do we already have this content?
-               $item_content = DBA::selectFirst('item-content', ['id'], ['uri-plink-hash' => $item['uri-hash']]);
+               $item_content = DBA::selectFirst('item-content', ['id'], ['uri-id' => $item['uri-id']]);
                if (DBA::isResult($item_content)) {
                        $item['icid'] = $item_content['id'];
                        logger('Fetched content for URI ' . $item['uri'] . ' (' . $item['icid'] . ')');
diff --git a/src/Model/Register.php b/src/Model/Register.php
new file mode 100644 (file)
index 0000000..e54db87
--- /dev/null
@@ -0,0 +1,131 @@
+<?php
+
+/**
+ * @file src/Model/Register.php
+ */
+namespace Friendica\Model;
+
+use Friendica\Database\DBA;
+use Friendica\Util\DateTimeFormat;
+
+/**
+ * Class interacting with the register database table
+ *
+ * @author Hypolite Petovan <mrpetovan@gmail.com>
+ */
+class Register
+{
+       /**
+        * Return the list of pending registrations
+        *
+        * @return array
+        */
+       public static function getPending()
+       {
+               $stmt = DBA::p(
+                       "SELECT `register`.*, `contact`.`name`, `user`.`email`
+                       FROM `register`
+                       INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
+                       INNER JOIN `user` ON `register`.`uid` = `user`.`uid`"
+               );
+
+               return DBA::toArray($stmt);
+       }
+
+       /**
+        * Returns the pending registration count
+        *
+        * @return int
+        */
+       public static function getPendingCount()
+       {
+               $register = DBA::fetchFirst(
+                       "SELECT COUNT(*) AS `count`
+                       FROM `register`
+                       INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid` AND `contact`.`self`"
+               );
+
+               return $register['count'];
+       }
+
+       /**
+        * Returns the register record associated with the provided hash
+        *
+        * @param  string $hash
+        * @return array
+        */
+       public static function getByHash($hash)
+       {
+               return DBA::selectFirst('register', [], ['hash' => $hash]);
+       }
+
+       /**
+        * Returns true if a register record exists with the provided hash
+        *
+        * @param  string  $hash
+        * @return boolean
+        */
+       public static function existsByHash($hash)
+       {
+               return DBA::exists('register', ['hash' => $hash]);
+       }
+
+       /**
+        * Creates a register record for an invitation and returns the auto-generated code for it
+        *
+        * @return string
+        */
+       public static function createForInvitation()
+       {
+               $code = autoname(8) . srand(1000, 9999);
+
+               $fields = [
+                       'hash' => $code,
+                       'created' => DateTimeFormat::utcNow()
+               ];
+
+               DBA::insert('register', $fields);
+
+               return $code;
+       }
+
+       /**
+        * Creates a register record for approval and returns the success of the database insert
+        * Checks for the existence of the provided user id
+        *
+        * @param  integer $uid      The ID of the user needing approval
+        * @param  string  $language The registration language
+        * @param  string  $note     An additional message from the user
+        * @return boolean
+        */
+       public static function createForApproval($uid, $language, $note = '')
+       {
+               $hash = random_string();
+
+               if (!User::exists($uid)) {
+                       return false;
+               }
+
+               $fields = [
+                       'hash'     => $hash,
+                       'created'  => DateTimeFormat::utcNow(),
+                       'uid'      => $uid,
+                       'password' => '', // Obsolete, slated for deletion
+                       'language' => $language,
+                       'note'     => $note
+               ];
+
+               return DBA::insert('register', $fields);
+       }
+
+       /**
+        * Deletes a register record by the provided hash and returns the success of the database deletion
+        *
+        * @param  string  $hash
+        * @return boolean
+        */
+       public static function deleteByHash($hash)
+       {
+               return DBA::delete('register', ['hash' => $hash]);
+       }
+}
index b8b694de87194a6bd6e143c9672c4b49782e9e2d..17c9831ca92530b5d8c9bdd1673094dbf518d6a8 100644 (file)
@@ -32,9 +32,29 @@ require_once 'include/text.php';
 class User
 {
        /**
-        * @brief Returns the user id of a given profile url
+        * Returns true if a user record exists with the provided id
         *
-        * @param string $profile
+        * @param  integer $uid
+        * @return boolean
+        */
+       public static function exists($uid)
+       {
+               return DBA::exists('user', ['uid' => $uid]);
+       }
+
+       /**
+        * @param  integer       $uid
+        * @return array|boolean User record if it exists, false otherwise
+        */
+       public static function getById($uid)
+       {
+               return DBA::selectFirst('user', [], ['uid' => $uid]);
+       }
+
+       /**
+        * @brief Returns the user id of a given profile URL
+        *
+        * @param string $url
         *
         * @return integer user id
         */
@@ -401,7 +421,7 @@ class User
                                throw new Exception(L10n::t('An invitation is required.'));
                        }
 
-                       if (!DBA::exists('register', ['hash' => $invite_id])) {
+                       if (!Register::existsByHash($invite_id)) {
                                throw new Exception(L10n::t('Invitation could not be verified.'));
                        }
                }
@@ -644,27 +664,36 @@ class User
        }
 
        /**
-        * @brief Sends pending registration confiÅ•mation email
+        * @brief Sends pending registration confirmation email
         *
-        * @param string $email
+        * @param array  $user     User record array
         * @param string $sitename
-        * @param string $username
+        * @param string $siteurl
+        * @param string $password Plaintext password
         * @return NULL|boolean from notification() and email() inherited
         */
-       public static function sendRegisterPendingEmail($email, $sitename, $username)
+       public static function sendRegisterPendingEmail($user, $sitename, $siteurl, $password)
        {
                $body = deindent(L10n::t('
                        Dear %1$s,
                                Thank you for registering at %2$s. Your account is pending for approval by the administrator.
-               '));
 
-               $body = sprintf($body, $username, $sitename);
+                       Your login details are as follows:
+
+                       Site Location:  %3$s
+                       Login Name:             %4$s
+                       Password:               %5$s
+               ',
+                       $user['username'], $sitename, $siteurl, $user['nickname'], $password
+               ));
 
                return notification([
-                       'type' => SYSTEM_EMAIL,
-                       'to_email' => $email,
-                       'subject'=> L10n::t('Registration at %s', $sitename),
-                       'body' => $body]);
+                       'type'     => SYSTEM_EMAIL,
+                       'uid'      => $user['uid'],
+                       'to_email' => $user['email'],
+                       'subject'  => L10n::t('Registration at %s', $sitename),
+                       'body'     => $body
+               ]);
        }
 
        /**
@@ -672,19 +701,20 @@ class User
         *
         * It's here as a function because the mail is sent from different parts
         *
-        * @param string $email
+        * @param array  $user     User record array
         * @param string $sitename
         * @param string $siteurl
-        * @param string $username
-        * @param string $password
+        * @param string $password Plaintext password
         * @return NULL|boolean from notification() and email() inherited
         */
-       public static function sendRegisterOpenEmail($email, $sitename, $siteurl, $username, $password, $user)
+       public static function sendRegisterOpenEmail($user, $sitename, $siteurl, $password)
        {
                $preamble = deindent(L10n::t('
                        Dear %1$s,
                                Thank you for registering at %2$s. Your account has been created.
-               '));
+               ',
+                       $preamble, $user['username'], $sitename
+               ));
                $body = deindent(L10n::t('
                        The login details are as follows:
 
@@ -711,19 +741,19 @@ class User
 
                        If you ever want to delete your account, you can do so at %3$s/removeme
 
-                       Thank you and welcome to %2$s.'));
-
-               $preamble = sprintf($preamble, $username, $sitename);
-               $body = sprintf($body, $email, $sitename, $siteurl, $username, $password);
+                       Thank you and welcome to %2$s.',
+                       $user['email'], $sitename, $siteurl, $user['username'], $password
+               ));
 
                return notification([
-                       'uid' => $user['uid'],
+                       'uid'      => $user['uid'],
                        'language' => $user['language'],
-                       'type' => SYSTEM_EMAIL,
-                       'to_email' => $email,
-                       'subject'=> L10n::t('Registration details for %s', $sitename),
-                       'preamble'=> $preamble,
-                       'body' => $body]);
+                       'type'     => SYSTEM_EMAIL,
+                       'to_email' => $user['email'],
+                       'subject'  => L10n::t('Registration details for %s', $sitename),
+                       'preamble' => $preamble,
+                       'body'     => $body
+               ]);
        }
 
        /**
@@ -760,7 +790,7 @@ class User
                if ($uid == local_user()) {
                        unset($_SESSION['authenticated']);
                        unset($_SESSION['uid']);
-                       goaway(System::baseUrl());
+                       goaway();;
                }
        }
 }
diff --git a/src/Module/Itemsource.php b/src/Module/Itemsource.php
new file mode 100644 (file)
index 0000000..bcbd557
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+namespace Friendica\Module;
+
+use Friendica\Core\L10n;
+use Friendica\Model;
+
+/**
+ * @author Hypolite Petovan <mrpetovan@gmail.com>
+ */
+class Itemsource extends \Friendica\BaseModule
+{
+       public static function content()
+       {
+               if (!is_site_admin()) {
+                       return;
+               }
+
+               $source = '';
+               $item_uri = '';
+               if (!empty($_REQUEST['guid'])) {
+                       $item = Model\Item::selectFirst([], ['guid' => $_REQUEST['guid']]);
+
+                       $conversation = Model\Conversation::getByItemUri($item['uri']);
+
+                       $item_uri = $item['uri'];
+                       $source = htmlspecialchars($conversation['source']);
+               }
+
+               $tpl = get_markup_template('debug/itemsource.tpl');
+               $o = replace_macros($tpl, [
+                       '$guid'          => ['guid', L10n::t('Item Guid'), htmlentities(defaults($_REQUEST, 'guid', '')), ''],
+                       '$source'        => $source,
+                       '$item_uri'      => $item_uri
+               ]);
+
+               return $o;
+       }
+}
index 48ffe65b74ed16b1b59fc8cd381d75a0604bfd2c..34a5f8138af27f1eb7deb9899652ddf9247a2f4b 100644 (file)
@@ -157,7 +157,7 @@ class Post extends BaseObject
                        if ($item["event-id"] != 0) {
                                $edpost = ["events/event/" . $item['event-id'], L10n::t("Edit")];
                        } else {
-                               $edpost = ["editpost/" . $item['id'] . "/" . base64_encode($a->cmd), L10n::t("Edit")];
+                               $edpost = ["editpost/" . $item['id'], L10n::t("Edit")];
                        }
                        $dropping = in_array($item['uid'], [0, local_user()]);
                } else {
index 0af8ee5e3545a157c96178eeb8455150eadefe10..23eb861721279a4a66a454306696d7b0c0342ddc 100644 (file)
@@ -63,7 +63,13 @@ class ActivityPub
                        return false;
                }
 
-               return json_decode($curlResult->getBody(), true);
+               $content = json_decode($curlResult->getBody(), true);
+
+               if (empty($content) || !is_array($content)) {
+                       return false;
+               }
+
+               return $content;
        }
 
        /**
index c481423a675c495349ad2d27c7d56f8009cbd5a9..9bafb5e17511cc10c2a35565b2003f78e9aff2f1 100644 (file)
@@ -272,7 +272,7 @@ class Processor
                $activity['cc'] = defaults($object, 'cc', []);
                $activity['actor'] = $child['author'];
                $activity['object'] = $object;
-               $activity['published'] = $object['published'];
+               $activity['published'] = defaults($object, 'published', $child['published']);
                $activity['type'] = 'Create';
 
                $ldactivity = JsonLD::compact($activity);
index 04da5fa596ea0858a6468a154eac71fba2b33833..a5ba0763db56a05bd83dd9abdce5b3e5c45921e1 100644 (file)
@@ -461,7 +461,7 @@ class Receiver
 
                logger('Switch contact ' . $cid . ' (' . $profile['url'] . ') for user ' . $uid . ' to ActivityPub');
 
-               $photo = $profile['photo'];
+               $photo = defaults($profile, 'photo', null);
                unset($profile['photo']);
                unset($profile['baseurl']);
 
@@ -478,7 +478,7 @@ class Receiver
        }
 
        /**
-        * 
+        *
         *
         * @param $receivers
         * @param $actor
@@ -503,12 +503,12 @@ class Receiver
        }
 
        /**
-        * 
+        *
         *
         * @param $object_data
         * @param array $activity
         *
-        * @return 
+        * @return
         */
        private static function addActivityFields($object_data, $activity)
        {
index 9ddcc1d7933c7a3e5b936650903b924533f5a245..2a930fcc6f337ea8e5a2a7557aaefc5fbf8fe739 100644 (file)
@@ -355,7 +355,7 @@ class Transmitter
 
                        foreach ($receiver_list as $receiver) {
                                $contact = DBA::selectFirst('contact', ['url'], ['id' => $receiver, 'network' => Protocol::ACTIVITYPUB]);
-                               if (empty($contacts[$contact['url']])) {
+                               if (DBA::isResult($contact) && empty($contacts[$contact['url']])) {
                                        $data['cc'][] = $contact['url'];
                                        $contacts[$contact['url']] = $contact['url'];
                                }
@@ -743,6 +743,26 @@ class Transmitter
                return $attachments;
        }
 
+        /**
+        * @brief Callback function to replace a Friendica style mention in a mention that is used on AP
+        *
+        * @param array $match Matching values for the callback
+        * @return string Replaced mention
+        */
+       private static function MentionCallback($match)
+       {
+               if (empty($match[1])) {
+                       return;
+               }
+
+               $data = Contact::getDetailsByURL($match[1]);
+               if (empty($data) || empty($data['nick'])) {
+                       return;
+               }
+
+               return '@[url=' . $data['url'] . ']' . $data['nick'] . '[/url]';
+       }
+
        /**
         * Remove image elements and replaces them with links to the image
         *
@@ -851,6 +871,9 @@ class Transmitter
                        $body = self::removePictures($body);
                }
 
+               $regexp = "/[@!]\[url\=([^\[\]]*)\].*?\[\/url\]/ism";
+               $body = preg_replace_callback($regexp, ['self', 'MentionCallback'], $body);
+
                $data['content'] = BBCode::convert($body, false, 7);
                $data['source'] = ['content' => $item['body'], 'mediaType' => "text/bbcode"];
 
index 00f4e1702d643779c6930f494dacc0b71882db62..5792d56b6eeef6cc0e28e6315cbb08f8ed939d6f 100644 (file)
@@ -949,6 +949,7 @@ class Diaspora
                                $person = DBA::selectFirst('fcontact', [], ['network' => Protocol::DIASPORA, 'addr' => $handle]);
                                if (!DBA::isResult($person)) {
                                        $person = $r;
+                                       $person['id'] = 0;
                                }
                        }
                }
@@ -1199,7 +1200,7 @@ class Diaspora
                );
 
                preg_replace_callback(
-                       "&\[url=/posts/([^\[\]]*)\](.*)\[\/url\]&Usi",
+                       "&\[url=/?posts/([^\[\]]*)\](.*)\[\/url\]&Usi",
                        function ($match) use ($item) {
                                self::fetchGuidSub($match, $item);
                        },
@@ -3429,12 +3430,9 @@ class Diaspora
                /// @todo - establish "all day" events in Friendica
                $eventdata["all_day"] = "false";
 
-               if (!$event['adjust']) {
+               $eventdata['timezone'] = 'UTC';
+               if (!$event['adjust'] && $user['timezone']) {
                        $eventdata['timezone'] = $user['timezone'];
-
-                       if ($eventdata['timezone'] == "") {
-                               $eventdata['timezone'] = 'UTC';
-                       }
                }
 
                if ($event['start']) {
index f2a5eccd395247956c9e39a4e22c037d9c0567fa..24089b9cbd2a92bb33c22fe4e41ee3b501987cff 100644 (file)
@@ -141,7 +141,7 @@ class ParseUrl
                }
 
                // If the file is too large then exit
-               if ($curlResult->getInfo()['download_content_length'] > 1000000) {
+               if (defaults($curlResult->getInfo(), 'download_content_length', 0) > 1000000) {
                        return $siteinfo;
                }
 
index f2951cce1ff2bf13deb7aec6e112f16bfcb655f8..1c353fb6327e8da4e3621e8344f7eaea51bb96d1 100644 (file)
@@ -39,13 +39,13 @@ class Delivery extends BaseObject
                $followup = false;
                $public_message = false;
 
+               $items = [];
                if ($cmd == self::MAIL) {
                        $target_item = DBA::selectFirst('mail', [], ['id' => $item_id]);
                        if (!DBA::isResult($target_item)) {
                                return;
                        }
                        $uid = $target_item['uid'];
-                       $items = [];
                } elseif ($cmd == self::SUGGESTION) {
                        $target_item = DBA::selectFirst('fsuggest', [], ['id' => $item_id]);
                        if (!DBA::isResult($target_item)) {
@@ -65,7 +65,6 @@ class Delivery extends BaseObject
                        $params = ['order' => ['id']];
                        $itemdata = Item::select([], $condition, $params);
 
-                       $items = [];
                        while ($item = Item::fetch($itemdata)) {
                                if ($item['id'] == $parent_id) {
                                        $parent = $item;
index 0066a04aedd06c7136576506d1e6695c3cd445f1..be6d5a549ebc6709a5f94ea5e8c95e8e35a892c9 100644 (file)
@@ -148,6 +148,10 @@ class OnePoll
                        }
                }
 
+               if (!in_array($contact['network'], [Protocol::FEED, Protocol::MAIL]) && Config::get('system', 'disable_polling')) {
+                       return;
+               }
+
                if ($importer_uid == 0) {
                        logger('Ignore public contacts');
 
@@ -345,7 +349,7 @@ class OnePoll
                } elseif ($contact['network'] === Protocol::MAIL) {
                        logger("Mail: Fetching for ".$contact['addr'], LOGGER_DEBUG);
 
-                       $mail_disabled = ((function_exists('imap_open') && (! Config::get('system', 'imap_disabled'))) ? 0 : 1);
+                       $mail_disabled = ((function_exists('imap_open') && !Config::get('system', 'imap_disabled')) ? 0 : 1);
                        if ($mail_disabled) {
                                // set the last-update so we don't keep polling
                                DBA::update('contact', ['last-update' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
@@ -541,7 +545,7 @@ class OnePoll
                                                        if ($datarray['parent-uri'] === $datarray['uri']) {
                                                                $datarray['private'] = 1;
                                                        }
-                                                       if (($contact['network'] === Protocol::MAIL) && (!PConfig::get($importer_uid, 'system', 'allow_public_email_replies'))) {
+                                                       if (($contact['network'] === Protocol::MAIL) && !PConfig::get($importer_uid, 'system', 'allow_public_email_replies')) {
                                                                $datarray['private'] = 1;
                                                                $datarray['allow_cid'] = '<' . $contact['id'] . '>';
                                                        }
index 56f285f2df9037f8f2dc405258f7bd51f495554b..d889e241e22061f56b549857a82995ce023c8957 100644 (file)
@@ -246,3 +246,12 @@ function update_1278() {
 
        return UPDATE_SUCCESS;
 }
+
+function update_1288() {
+       // Updates missing `uri-id` values
+
+       DBA::e("UPDATE `item-activity` INNER JOIN `item` ON `item`.`iaid` = `item-activity`.`id` SET `item-activity`.`uri-id` = `item`.`uri-id` WHERE `item-activity`.`uri-id` IS NULL OR `item-activity`.`uri-id` = 0");
+       DBA::e("UPDATE `item-content` INNER JOIN `item` ON `item`.`icid` = `item-content`.`id` SET `item-content`.`uri-id` = `item`.`uri-id` WHERE `item-content`.`uri-id` IS NULL OR `item-content`.`uri-id` = 0");
+
+       return UPDATE_SUCCESS;
+}
index 344ee296a2056f244c3992c2341b38957cda5fd5..b4c34f74e2ca3a08f7ca52207837f963f0143856 100644 (file)
@@ -5,7 +5,7 @@
 
 
        <div id="contact-edit-nav-wrapper" >
-               <form action="contacts/{{$contact_id}}" method="post" >
+               <form action="contact/{{$contact_id}}" method="post" >
                        <div id="contact-edit-links">
                                <div id="contact-edit-status-wrapper">
                                        <span id="contact-edit-contact-status">{{$contact_status}}</span>
diff --git a/view/templates/debug/itemsource.tpl b/view/templates/debug/itemsource.tpl
new file mode 100644 (file)
index 0000000..377409e
--- /dev/null
@@ -0,0 +1,28 @@
+<h2>Item Source</h2>
+<form action="itemsource" method="get" class="panel panel-default">
+       <div class="panel-body">
+               <div class="form-group">
+                       {{include file="field_input.tpl" field=$guid}}
+               </div>
+               <p><button type="submit" class="btn btn-primary">Submit</button></p>
+       </div>
+</form>
+
+{{if $source}}
+<div class="itemsource-results">
+       <div class="panel panel-default">
+               <div class="panel-heading">
+                       <h3 class="panel-title">Item URI</h3>
+               </div>
+               <div class="panel-body">
+                       {{$item_uri}}
+               </div>
+       </div>
+       <div class="panel panel-default">
+               <div class="panel-heading">
+                       <h3 class="panel-title">Source</h3>
+               </div>
+               <pre><code class="language-php">{{$source}}</code></pre>
+       </div>
+</div>
+{{/if}}
index 4c12948dcef1b3d88d6d5b9e3385bd322b10e1b0..04426eeb12aa5b799d2cc2af2e1b1ae141d0c245 100644 (file)
@@ -9,7 +9,7 @@
 
 
                <div id="contact-edit-content-wrapper">
-                       <form action="contacts/{{$contact_id}}" method="post" >
+                       <form action="contact/{{$contact_id}}" method="post" >
 
                                {{* This is the Action menu where contact related actions like 'ignore', 'hide' can be performed *}}
                                <ul id="contact-edit-actions" class="nav nav-pills preferences">
index 63069a772138a48ecddaf8cd9bcae3496bd45938..9014be1d252356f5ee5d435ec8548d3cb98fbf6b 100644 (file)
@@ -6,7 +6,7 @@
 
 
        <div id="contact-edit-nav-wrapper" >
-               <form action="contacts/{{$contact_id}}" method="post" >
+               <form action="contact/{{$contact_id}}" method="post" >
                        <div id="contact-edit-links">
                                <div id="contact-edit-status-wrapper">
                                        <span id="contact-edit-contact-status">{{$contact_status}}</span>