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);
/**
/**
* @brief Redirect to another URL and terminate this process.
*/
-function goaway($path)
+function goaway($path = '')
{
if (strstr(normalise_link($path), 'http://')) {
$url = $path;
; 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 =
"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": {
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;
// 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";
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';
/**
* @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
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);
$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');
}
/* 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");
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')) {
use Friendica\Core\PConfig;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
+use Friendica\Model\Item;
function community_init(App $a)
{
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);
}
$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');
}
$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()]);
$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'),
}
goaway($return_url);
} elseif ($result['cid']) {
- goaway('contacts/' . $result['cid']);
+ goaway('contact/' . $result['cid']);
}
info(L10n::t('The contact could not be added.'));
}
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) {
$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
$hdrs[$k] = $v;
}
}
+ $type = null;
if (array_key_exists('Content-Type', $hdrs)) {
$type = $hdrs['Content-Type'];
}
$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);
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';
$arr['language'] = L10n::getBrowserLanguage();
try {
- $result = User::create($arr);
+ $result = Model\User::create($arr);
} catch (Exception $e) {
notice($e->getMessage());
return;
$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);
}
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.',
}
} 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);
}
'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',
]);
}
// 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;
use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
+use Friendica\Model\Register;
use Friendica\Model\User;
use Friendica\Module\Login;
{
$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();
// 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;
}
{
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];
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/');
}
}
$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'));
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
}
}
/**
- * 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("♲ ", ENT_QUOTES, 'UTF-8') . ' <a href="' . $profile . '">' . $userid . "</a>: <br />»" . $share[3] . "«";
+ $text = ($is_quote_share? '<br />' : '') . '<p>' . html_entity_decode('♲ ', ENT_QUOTES, 'UTF-8') . ' <a href="' . $attributes['profile'] . '">' . $mention . '</a>: </p>' . "\n" . '«' . $content . '»';
break;
case 2:
- $text = $preshare . html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8') . ' ' . $userid_compact . ": <br />" . $share[3];
+ $text = ($is_quote_share? '<br />' : '') . '<p>' . html_entity_decode('♲ ', ENT_QUOTES, 'UTF-8') . ' ' . $author_contact['addr'] . ': </p>' . "\n" . $content;
break;
case 3: // Diaspora
- $headline = '<b>' . html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8') . $userid . ':</b><br />';
-
- $text = trim($share[1]);
-
- if ($text != "") {
- $text .= "<hr />";
- }
+ $headline = '<p><b>' . html_entity_decode('♲ ', 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("♲ ", 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('♲ ', 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("♲ ", ENT_QUOTES, 'UTF-8') . ' ' . $userid_compact . ": <br />" . $share[3];
+ $text = ($is_quote_share? '<br />' : '') . '<p>' . html_entity_decode('♲ ', ENT_QUOTES, 'UTF-8') . ' ' . $author_contact['addr'] . ': </p>' . "\n" . $content;
break;
case 7: // statusnet/GNU Social
- $text = $preshare . html_entity_decode("♲ ", 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('♲ ', ENT_QUOTES, 'UTF-8') . ' @' . $author_contact['addr'] . ': ' . $content . '</p>' . "\n";
break;
case 9: // Google+
- $text = $preshare . html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8') . ' ' . $userid_compact . ": <br />" . $share[3];
+ $text = ($is_quote_share? '<br />' : '') . '<p>' . html_entity_decode('♲ ', 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;
// 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
$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);
}
}
+ // 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;
* @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) {
* @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);
}
}
- 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"];
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
*
// 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',
$usermode = true;
}
- $fields = self::fieldlist($selected, $usermode);
+ $fields = self::fieldlist($usermode);
$select_fields = self::constructSelectFields($fields, $selected);
$usermode = true;
}
- $fields = self::fieldlist($selected, $usermode);
+ $fields = self::fieldlist($usermode);
$fields['thread'] = ['mention', 'ignored', 'iid'];
*
* @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',
}
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) {
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
*
// 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) {
$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) {
}
}
} 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
}
}
- // 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', ''));
$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.');
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) {
}
// 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'] . ')');
*/
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])) {
}
// 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'] . ')');
--- /dev/null
+<?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]);
+ }
+}
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
*/
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.'));
}
}
}
/**
- * @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
+ ]);
}
/**
*
* 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:
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
+ ]);
}
/**
if ($uid == local_user()) {
unset($_SESSION['authenticated']);
unset($_SESSION['uid']);
- goaway(System::baseUrl());
+ goaway();;
}
}
}
--- /dev/null
+<?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;
+ }
+}
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 {
return false;
}
- return json_decode($curlResult->getBody(), true);
+ $content = json_decode($curlResult->getBody(), true);
+
+ if (empty($content) || !is_array($content)) {
+ return false;
+ }
+
+ return $content;
}
/**
$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);
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']);
}
/**
- *
+ *
*
* @param $receivers
* @param $actor
}
/**
- *
+ *
*
* @param $object_data
* @param array $activity
*
- * @return
+ * @return
*/
private static function addActivityFields($object_data, $activity)
{
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'];
}
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
*
$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"];
$person = DBA::selectFirst('fcontact', [], ['network' => Protocol::DIASPORA, 'addr' => $handle]);
if (!DBA::isResult($person)) {
$person = $r;
+ $person['id'] = 0;
}
}
}
);
preg_replace_callback(
- "&\[url=/posts/([^\[\]]*)\](.*)\[\/url\]&Usi",
+ "&\[url=/?posts/([^\[\]]*)\](.*)\[\/url\]&Usi",
function ($match) use ($item) {
self::fetchGuidSub($match, $item);
},
/// @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']) {
}
// 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;
}
$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)) {
$params = ['order' => ['id']];
$itemdata = Item::select([], $condition, $params);
- $items = [];
while ($item = Item::fetch($itemdata)) {
if ($item['id'] == $parent_id) {
$parent = $item;
}
}
+ if (!in_array($contact['network'], [Protocol::FEED, Protocol::MAIL]) && Config::get('system', 'disable_polling')) {
+ return;
+ }
+
if ($importer_uid == 0) {
logger('Ignore public contacts');
} 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']]);
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'] . '>';
}
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;
+}
<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>
--- /dev/null
+<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}}
<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">
<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>