Merge remote-tracking branch 'upstream/develop' into archive-contact

This commit is contained in:
Michael 2017-12-04 19:05:53 +00:00
commit 3bb53967f4
32 changed files with 864 additions and 767 deletions

View file

@ -36,7 +36,6 @@ require_once 'include/text.php';
require_once 'include/datetime.php'; require_once 'include/datetime.php';
require_once 'include/pgettext.php'; require_once 'include/pgettext.php';
require_once 'include/nav.php'; require_once 'include/nav.php';
require_once 'include/features.php';
require_once 'include/identity.php'; require_once 'include/identity.php';
require_once 'update.php'; require_once 'update.php';
require_once 'include/dbstructure.php'; require_once 'include/dbstructure.php';

View file

@ -1,10 +1,9 @@
<?php <?php
/** /**
* @file include/acl_selectors.php * @file include/acl_selectors.php
*/ */
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Database\DBM; use Friendica\Database\DBM;
use Friendica\Model\GlobalContact; use Friendica\Model\GlobalContact;
@ -12,10 +11,8 @@ use Friendica\Object\Contact;
require_once "include/contact_selectors.php"; require_once "include/contact_selectors.php";
require_once "include/contact_widgets.php"; require_once "include/contact_widgets.php";
require_once "include/features.php";
require_once "mod/proxy.php"; require_once "mod/proxy.php";
/** /**
* @package acl_selectors * @package acl_selectors
*/ */
@ -380,7 +377,7 @@ function populate_acl($user = null, $show_jotnets = false) {
'$aclModalTitle' => t('Permissions'), '$aclModalTitle' => t('Permissions'),
'$aclModalDismiss' => t('Close'), '$aclModalDismiss' => t('Close'),
'$features' => array( '$features' => array(
'aclautomention' => (feature_enabled($user['uid'], "aclautomention") ? "true" : "false") 'aclautomention' => (Feature::isEnabled($user['uid'], "aclautomention") ? "true" : "false")
), ),
)); ));

View file

@ -6,6 +6,7 @@
* @todo Automatically detect if incoming data is HTML or BBCode * @todo Automatically detect if incoming data is HTML or BBCode
*/ */
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\NotificationsManager; use Friendica\Core\NotificationsManager;
@ -5100,7 +5101,7 @@ function api_friendica_profile_show($type)
$profileid = (x($_REQUEST, 'profile_id') ? $_REQUEST['profile_id'] : 0); $profileid = (x($_REQUEST, 'profile_id') ? $_REQUEST['profile_id'] : 0);
// retrieve general information about profiles for user // retrieve general information about profiles for user
$multi_profiles = feature_enabled(api_user(), 'multi_profiles'); $multi_profiles = Feature::isEnabled(api_user(), 'multi_profiles');
$directory = Config::get('system', 'directory'); $directory = Config::get('system', 'directory');
// get data of the specified profile id or all profiles of the user if not specified // get data of the specified profile id or all profiles of the user if not specified

View file

@ -1,5 +1,8 @@
<?php <?php
/**
* @file include/contact_widgets.php
*/
use Friendica\Content\Feature;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
@ -105,7 +108,7 @@ function networks_widget($baseurl, $selected = '') {
return ''; return '';
} }
if (!feature_enabled(local_user(), 'networks')) { if (!Feature::isEnabled(local_user(), 'networks')) {
return ''; return '';
} }
@ -144,7 +147,7 @@ function fileas_widget($baseurl, $selected = '') {
return ''; return '';
} }
if (! feature_enabled(local_user(), 'filing')) { if (! Feature::isEnabled(local_user(), 'filing')) {
return ''; return '';
} }
@ -178,7 +181,7 @@ function categories_widget($baseurl, $selected = '') {
$a = get_app(); $a = get_app();
if (! feature_enabled($a->profile['profile_uid'], 'categories')) { if (! Feature::isEnabled($a->profile['profile_uid'], 'categories')) {
return ''; return '';
} }

View file

@ -3,6 +3,7 @@
* @file include/conversation.php * @file include/conversation.php
*/ */
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
use Friendica\Core\System; use Friendica\Core\System;
@ -915,7 +916,7 @@ function conversation(App $a, $items, $mode, $update, $preview = false) {
'$mode' => $mode, '$mode' => $mode,
'$user' => $a->user, '$user' => $a->user,
'$threads' => $threads, '$threads' => $threads,
'$dropping' => ($page_dropping && feature_enabled(local_user(), 'multi_delete') ? t('Delete Selected Items') : False), '$dropping' => ($page_dropping && Feature::isEnabled(local_user(), 'multi_delete') ? t('Delete Selected Items') : False),
)); ));
return $o; return $o;
@ -1305,7 +1306,7 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false) {
'$title' => $x['title'], '$title' => $x['title'],
'$placeholdertitle' => t('Set title'), '$placeholdertitle' => t('Set title'),
'$category' => $x['category'], '$category' => $x['category'],
'$placeholdercategory' => (feature_enabled(local_user(), 'categories') ? t('Categories (comma-separated list)') : ''), '$placeholdercategory' => (Feature::isEnabled(local_user(), 'categories') ? t('Categories (comma-separated list)') : ''),
'$wait' => t('Please wait'), '$wait' => t('Please wait'),
'$permset' => t('Permission settings'), '$permset' => t('Permission settings'),
'$shortpermset' => t('permissions'), '$shortpermset' => t('permissions'),
@ -1321,7 +1322,7 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false) {
'$lockstate' => $x['lockstate'], '$lockstate' => $x['lockstate'],
'$bang' => $x['bang'], '$bang' => $x['bang'],
'$profile_uid' => $x['profile_uid'], '$profile_uid' => $x['profile_uid'],
'$preview' => ((feature_enabled($x['profile_uid'],'preview')) ? t('Preview') : ''), '$preview' => ((Feature::isEnabled($x['profile_uid'],'preview')) ? t('Preview') : ''),
'$jotplugins' => $jotplugins, '$jotplugins' => $jotplugins,
'$notes_cid' => $notes_cid, '$notes_cid' => $notes_cid,
'$sourceapp' => t($a->sourcename), '$sourceapp' => t($a->sourcename),

View file

@ -5,6 +5,7 @@
*/ */
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Database\DBM; use Friendica\Database\DBM;
@ -899,7 +900,7 @@ function widget_events() {
* for exporting the cal is enabled (otherwise the widget would appear for logged in users * for exporting the cal is enabled (otherwise the widget would appear for logged in users
* on foreigen profile pages even if the widget is disabled). * on foreigen profile pages even if the widget is disabled).
*/ */
if (intval($owner_uid) && local_user() !== $owner_uid && ! feature_enabled($owner_uid, "export_calendar")) { if (intval($owner_uid) && local_user() !== $owner_uid && ! Feature::isEnabled($owner_uid, "export_calendar")) {
return; return;
} }
@ -907,7 +908,7 @@ function widget_events() {
* If it's a kind of profile page (intval($owner_uid)) return if the user not logged in and * If it's a kind of profile page (intval($owner_uid)) return if the user not logged in and
* export feature isn't enabled. * export feature isn't enabled.
*/ */
if (intval($owner_uid) && ! local_user() && ! feature_enabled($owner_uid, "export_calendar")) { if (intval($owner_uid) && ! local_user() && ! Feature::isEnabled($owner_uid, "export_calendar")) {
return; return;
} }

View file

@ -1,144 +0,0 @@
<?php
/**
* @file include/features.php
* @brief Features management
*/
use Friendica\Core\Config;
use Friendica\Core\PConfig;
/**
* @brief check if feature is enabled
*
* @return boolean
*/
function feature_enabled($uid, $feature) {
$x = Config::get('feature_lock', $feature, false);
if ($x === false) {
$x = PConfig::get($uid, 'feature', $feature, false);
}
if ($x === false) {
$x = Config::get('feature', $feature, false);
}
if ($x === false) {
$x = get_feature_default($feature);
}
$arr = array('uid' => $uid, 'feature' => $feature, 'enabled' => $x);
call_hooks('feature_enabled',$arr);
return($arr['enabled']);
}
/**
* @brief check if feature is enabled or disabled by default
*
* @param string $feature
* @return boolean
*/
function get_feature_default($feature) {
$f = get_features();
foreach ($f as $cat) {
foreach ($cat as $feat) {
if (is_array($feat) && $feat[0] === $feature)
return $feat[3];
}
}
return false;
}
/**
* @brief Get a list of all available features
*
* The array includes the setting group, the setting name,
* explainations for the setting and if it's enabled or disabled
* by default
*
* @param bool $filtered True removes any locked features
*
* @return array
*/
function get_features($filtered = true) {
$arr = array(
// General
'general' => array(
t('General Features'),
//array('expire', t('Content Expiration'), t('Remove old posts/comments after a period of time')),
array('multi_profiles', t('Multiple Profiles'), t('Ability to create multiple profiles'), false, Config::get('feature_lock','multi_profiles', false)),
array('photo_location', t('Photo Location'), t('Photo metadata is normally stripped. This extracts the location (if present) prior to stripping metadata and links it to a map.'), false, Config::get('feature_lock','photo_location', false)),
array('export_calendar', t('Export Public Calendar'), t('Ability for visitors to download the public calendar'), false, Config::get('feature_lock','export_calendar', false)),
),
// Post composition
'composition' => array(
t('Post Composition Features'),
array('preview', t('Post Preview'), t('Allow previewing posts and comments before publishing them'), false, Config::get('feature_lock','preview', false)),
array('aclautomention', t('Auto-mention Forums'), t('Add/remove mention when a forum page is selected/deselected in ACL window.'), false, Config::get('feature_lock','aclautomention', false)),
),
// Network sidebar widgets
'widgets' => array(
t('Network Sidebar Widgets'),
array('archives', t('Search by Date'), t('Ability to select posts by date ranges'), false, Config::get('feature_lock','archives', false)),
array('forumlist_widget', t('List Forums'), t('Enable widget to display the forums your are connected with'), true, Config::get('feature_lock','forumlist_widget', false)),
array('groups', t('Group Filter'), t('Enable widget to display Network posts only from selected group'), false, Config::get('feature_lock','groups', false)),
array('networks', t('Network Filter'), t('Enable widget to display Network posts only from selected network'), false, Config::get('feature_lock','networks', false)),
array('savedsearch', t('Saved Searches'), t('Save search terms for re-use'), false, Config::get('feature_lock','savedsearch', false)),
),
// Network tabs
'net_tabs' => array(
t('Network Tabs'),
array('personal_tab', t('Network Personal Tab'), t('Enable tab to display only Network posts that you\'ve interacted on'), false, Config::get('feature_lock','personal_tab', false)),
array('new_tab', t('Network New Tab'), t('Enable tab to display only new Network posts (from the last 12 hours)'), false, Config::get('feature_lock','new_tab', false)),
array('link_tab', t('Network Shared Links Tab'), t('Enable tab to display only Network posts with links in them'), false, Config::get('feature_lock','link_tab', false)),
),
// Item tools
'tools' => array(
t('Post/Comment Tools'),
array('multi_delete', t('Multiple Deletion'), t('Select and delete multiple posts/comments at once'), false, Config::get('feature_lock','multi_delete', false)),
array('edit_posts', t('Edit Sent Posts'), t('Edit and correct posts and comments after sending'), false, Config::get('feature_lock','edit_posts', false)),
array('commtag', t('Tagging'), t('Ability to tag existing posts'), false, Config::get('feature_lock','commtag', false)),
array('categories', t('Post Categories'), t('Add categories to your posts'), false, Config::get('feature_lock','categories', false)),
array('filing', t('Saved Folders'), t('Ability to file posts under folders'), false, Config::get('feature_lock','filing', false)),
array('dislike', t('Dislike Posts'), t('Ability to dislike posts/comments'), false, Config::get('feature_lock','dislike', false)),
array('star_posts', t('Star Posts'), t('Ability to mark special posts with a star indicator'), false, Config::get('feature_lock','star_posts', false)),
array('ignore_posts', t('Mute Post Notifications'), t('Ability to mute notifications for a thread'), false, Config::get('feature_lock','ignore_posts', false)),
),
// Advanced Profile Settings
'advanced_profile' => array(
t('Advanced Profile Settings'),
array('forumlist_profile', t('List Forums'), t('Show visitors public community forums at the Advanced Profile Page'), false, Config::get('feature_lock','forumlist_profile', false)),
array('tagadelic', t('Tag Cloud'), t('Provide a personal tag cloud on your profile page'), false, Config::get('feature_lock', 'tagadelic', false)),
),
);
// removed any locked features and remove the entire category if this makes it empty
if ($filtered) {
foreach ($arr as $k => $x) {
$has_items = false;
$kquantity = count($arr[$k]);
for ($y = 0; $y < $kquantity; $y ++) {
if (is_array($arr[$k][$y])) {
if ($arr[$k][$y][4] === false) {
$has_items = true;
} else {
unset($arr[$k][$y]);
}
}
}
if (! $has_items) {
unset($arr[$k]);
}
}
}
call_hooks('get_features',$arr);
return $arr;
}

View file

@ -4,6 +4,7 @@
*/ */
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Content\ForumManager; use Friendica\Content\ForumManager;
use Friendica\Core\Cache; use Friendica\Core\Cache;
use Friendica\Core\Config; use Friendica\Core\Config;
@ -309,7 +310,7 @@ function profile_sidebar($profile, $block = 0)
} }
// show edit profile to yourself // show edit profile to yourself
if (!$is_contact && $profile['uid'] == local_user() && feature_enabled(local_user(), 'multi_profiles')) { if (!$is_contact && $profile['uid'] == local_user() && Feature::isEnabled(local_user(), 'multi_profiles')) {
$profile['edit'] = array(System::baseUrl(). '/profiles', t('Profiles'),"", t('Manage/edit profiles')); $profile['edit'] = array(System::baseUrl(). '/profiles', t('Profiles'),"", t('Manage/edit profiles'));
$r = q( $r = q(
"SELECT * FROM `profile` WHERE `uid` = %d", "SELECT * FROM `profile` WHERE `uid` = %d",
@ -336,7 +337,7 @@ function profile_sidebar($profile, $block = 0)
} }
} }
} }
if (!$is_contact && $profile['uid'] == local_user() && !feature_enabled(local_user(), 'multi_profiles')) { if (!$is_contact && $profile['uid'] == local_user() && !Feature::isEnabled(local_user(), 'multi_profiles')) {
$profile['edit'] = array(System::baseUrl(). '/profiles/'.$profile['id'], t('Edit profile'),"", t('Edit profile')); $profile['edit'] = array(System::baseUrl(). '/profiles/'.$profile['id'], t('Edit profile'),"", t('Edit profile'));
$profile['menu'] = array( $profile['menu'] = array(
'chg_photo' => t('Change profile photo'), 'chg_photo' => t('Change profile photo'),
@ -790,7 +791,7 @@ function advanced_profile(App $a)
} }
//show subcribed forum if it is enabled in the usersettings //show subcribed forum if it is enabled in the usersettings
if (feature_enabled($uid, 'forumlist_profile')) { if (Feature::isEnabled($uid, 'forumlist_profile')) {
$profile['forumlist'] = array( t('Forums:'), ForumManager::profileAdvanced($uid)); $profile['forumlist'] = array( t('Forums:'), ForumManager::profileAdvanced($uid));
} }

View file

@ -4,6 +4,7 @@
*/ */
use Friendica\App; use Friendica\App;
use Friendica\ParseUrl; use Friendica\ParseUrl;
use Friendica\Content\Feature;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
use Friendica\Core\Worker; use Friendica\Core\Worker;
@ -2359,7 +2360,7 @@ function posted_dates($uid, $wall) {
function posted_date_widget($url, $uid, $wall) { function posted_date_widget($url, $uid, $wall) {
$o = ''; $o = '';
if (! feature_enabled($uid, 'archives')) { if (! Feature::isEnabled($uid, 'archives')) {
return $o; return $o;
} }

View file

@ -1,6 +1,9 @@
<?php <?php
/**
* @file include/nav.php
*/
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Database\DBM; use Friendica\Database\DBM;
@ -190,7 +193,7 @@ function nav_info(App $a)
$nav['settings'] = array('settings', t('Settings'), '', t('Account settings')); $nav['settings'] = array('settings', t('Settings'), '', t('Account settings'));
if (feature_enabled(local_user(), 'multi_profiles')) { if (Feature::isEnabled(local_user(), 'multi_profiles')) {
$nav['profiles'] = array('profiles', t('Profiles'), '', t('Manage/Edit Profiles')); $nav['profiles'] = array('profiles', t('Profiles'), '', t('Manage/Edit Profiles'));
} }

View file

@ -1,40 +0,0 @@
<?php
class pidfile {
private $_file;
private $_running;
public function __construct($dir, $name) {
$this->_file = "$dir/$name.pid";
if (file_exists($this->_file)) {
$pid = trim(@file_get_contents($this->_file));
if (($pid != "") && posix_kill($pid, 0)) {
$this->_running = true;
}
}
if (! $this->_running) {
$pid = getmypid();
file_put_contents($this->_file, $pid);
}
}
public function __destruct() {
if ((! $this->_running) && file_exists($this->_file)) {
@unlink($this->_file);
}
}
public function is_already_running() {
return $this->_running;
}
public function running_time() {
return(time() - @filectime($this->_file));
}
public function kill() {
if (file_exists($this->_file))
return(posix_kill(file_get_contents($this->_file), SIGTERM));
}
}

View file

@ -1,6 +1,9 @@
<?php <?php
/**
* @file include/tags.php
*/
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Database\DBM; use Friendica\Database\DBM;
use Friendica\Object\Contact; use Friendica\Object\Contact;
@ -302,7 +305,7 @@ function tagcloud_wall_widget($limit = 50) {
return ""; return "";
} }
if(feature_enabled($a->profile['profile_uid'], 'tagadelic')) { if(Feature::isEnabled($a->profile['profile_uid'], 'tagadelic')) {
$owner_id = Contact::getIdForURL($a->profile['url']); $owner_id = Contact::getIdForURL($a->profile['url']);
if(!$owner_id) { if(!$owner_id) {

View file

@ -1,6 +1,9 @@
<?php <?php
/**
* @file include/text.php
*/
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Content\Smilies; use Friendica\Content\Smilies;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
@ -1046,7 +1049,7 @@ function search($s, $id = 'search-box', $url = 'search', $save = false, $aside =
'$action_url' => $url, '$action_url' => $url,
'$search_label' => t('Search'), '$search_label' => t('Search'),
'$save_label' => t('Save'), '$save_label' => t('Save'),
'$savedsearch' => feature_enabled(local_user(),'savedsearch'), '$savedsearch' => Feature::isEnabled(local_user(),'savedsearch'),
'$search_hint' => t('@name, !forum, #tags, content'), '$search_hint' => t('@name, !forum, #tags, content'),
); );

View file

@ -1,453 +0,0 @@
<?php
/**
* @file include/user.php
*/
use Friendica\Core\Config;
use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Object\Photo;
require_once 'include/network.php';
require_once 'include/plugin.php';
require_once 'include/text.php';
require_once 'include/pgettext.php';
require_once 'include/datetime.php';
require_once 'include/enotify.php';
function create_user($arr) {
// Required: { username, nickname, email } or { openid_url }
$a = get_app();
$result = array('success' => false, 'user' => null, 'password' => '', 'message' => '');
$using_invites = Config::get('system','invitation_only');
$num_invites = Config::get('system','number_invites');
$invite_id = ((x($arr,'invite_id')) ? notags(trim($arr['invite_id'])) : '');
$username = ((x($arr,'username')) ? notags(trim($arr['username'])) : '');
$nickname = ((x($arr,'nickname')) ? notags(trim($arr['nickname'])) : '');
$email = ((x($arr,'email')) ? notags(trim($arr['email'])) : '');
$openid_url = ((x($arr,'openid_url')) ? notags(trim($arr['openid_url'])) : '');
$photo = ((x($arr,'photo')) ? notags(trim($arr['photo'])) : '');
$password = ((x($arr,'password')) ? trim($arr['password']) : '');
$password1 = ((x($arr,'password1')) ? trim($arr['password1']) : '');
$confirm = ((x($arr,'confirm')) ? trim($arr['confirm']) : '');
$blocked = ((x($arr,'blocked')) ? intval($arr['blocked']) : 0);
$verified = ((x($arr,'verified')) ? intval($arr['verified']) : 0);
$publish = ((x($arr,'profile_publish_reg') && intval($arr['profile_publish_reg'])) ? 1 : 0);
$netpublish = ((strlen(Config::get('system','directory'))) ? $publish : 0);
if ($password1 != $confirm) {
$result['message'] .= t('Passwords do not match. Password unchanged.') . EOL;
return $result;
} elseif ($password1 != "")
$password = $password1;
$tmp_str = $openid_url;
if($using_invites) {
if(! $invite_id) {
$result['message'] .= t('An invitation is required.') . EOL;
return $result;
}
$r = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1", dbesc($invite_id));
if(! results($r)) {
$result['message'] .= t('Invitation could not be verified.') . EOL;
return $result;
}
}
if((! x($username)) || (! x($email)) || (! x($nickname))) {
if($openid_url) {
if(! validate_url($tmp_str)) {
$result['message'] .= t('Invalid OpenID url') . EOL;
return $result;
}
$_SESSION['register'] = 1;
$_SESSION['openid'] = $openid_url;
require_once('library/openid.php');
$openid = new LightOpenID;
$openid->identity = $openid_url;
$openid->returnUrl = System::baseUrl() . '/openid';
$openid->required = array('namePerson/friendly', 'contact/email', 'namePerson');
$openid->optional = array('namePerson/first','media/image/aspect11','media/image/default');
try {
$authurl = $openid->authUrl();
} catch (Exception $e){
$result['message'] .= t("We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID."). EOL . EOL . t("The error message was:") . $e->getMessage() . EOL;
return $result;
}
goaway($authurl);
// NOTREACHED
}
notice( t('Please enter the required information.') . EOL );
return;
}
if(! validate_url($tmp_str))
$openid_url = '';
$err = '';
// collapse multiple spaces in name
$username = preg_replace('/ +/',' ',$username);
if(mb_strlen($username) > 48)
$result['message'] .= t('Please use a shorter name.') . EOL;
if(mb_strlen($username) < 3)
$result['message'] .= t('Name too short.') . EOL;
// So now we are just looking for a space in the full name.
$loose_reg = Config::get('system','no_regfullname');
if(! $loose_reg) {
$username = mb_convert_case($username,MB_CASE_TITLE,'UTF-8');
if(! strpos($username,' '))
$result['message'] .= t("That doesn't appear to be your full \x28First Last\x29 name.") . EOL;
}
if(! allowed_email($email))
$result['message'] .= t('Your email domain is not among those allowed on this site.') . EOL;
if((! valid_email($email)) || (! validate_email($email)))
$result['message'] .= t('Not a valid email address.') . EOL;
// Disallow somebody creating an account using openid that uses the admin email address,
// since openid bypasses email verification. We'll allow it if there is not yet an admin account.
$adminlist = explode(",", str_replace(" ", "", strtolower($a->config['admin_email'])));
//if((x($a->config,'admin_email')) && (strcasecmp($email,$a->config['admin_email']) == 0) && strlen($openid_url)) {
if((x($a->config,'admin_email')) && in_array(strtolower($email), $adminlist) && strlen($openid_url)) {
$r = q("SELECT * FROM `user` WHERE `email` = '%s' LIMIT 1",
dbesc($email)
);
if (DBM::is_result($r))
$result['message'] .= t('Cannot use that email.') . EOL;
}
$nickname = $arr['nickname'] = strtolower($nickname);
if(! preg_match("/^[a-z0-9][a-z0-9\_]*$/",$nickname))
$result['message'] .= t('Your "nickname" can only contain "a-z", "0-9" and "_".') . EOL;
$r = q("SELECT `uid` FROM `user`
WHERE `nickname` = '%s' LIMIT 1",
dbesc($nickname)
);
if (DBM::is_result($r))
$result['message'] .= t('Nickname is already registered. Please choose another.') . EOL;
// Check deleted accounts that had this nickname. Doesn't matter to us,
// but could be a security issue for federated platforms.
$r = q("SELECT * FROM `userd`
WHERE `username` = '%s' LIMIT 1",
dbesc($nickname)
);
if (DBM::is_result($r))
$result['message'] .= t('Nickname was once registered here and may not be re-used. Please choose another.') . EOL;
if(strlen($result['message'])) {
return $result;
}
$new_password = ((strlen($password)) ? $password : autoname(6) . mt_rand(100,9999));
$new_password_encoded = hash('whirlpool',$new_password);
$result['password'] = $new_password;
require_once('include/crypto.php');
$keys = new_keypair(4096);
if($keys === false) {
$result['message'] .= t('SERIOUS ERROR: Generation of security keys failed.') . EOL;
return $result;
}
$prvkey = $keys['prvkey'];
$pubkey = $keys['pubkey'];
// Create another keypair for signing/verifying salmon protocol messages.
$sres = new_keypair(512);
$sprvkey = $sres['prvkey'];
$spubkey = $sres['pubkey'];
$r = q("INSERT INTO `user` (`guid`, `username`, `password`, `email`, `openid`, `nickname`,
`pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked`, `timezone`, `default-location`)
VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, 'UTC', '')",
dbesc(generate_user_guid()),
dbesc($username),
dbesc($new_password_encoded),
dbesc($email),
dbesc($openid_url),
dbesc($nickname),
dbesc($pubkey),
dbesc($prvkey),
dbesc($spubkey),
dbesc($sprvkey),
dbesc(datetime_convert()),
intval($verified),
intval($blocked)
);
if ($r) {
$r = q("SELECT * FROM `user`
WHERE `username` = '%s' AND `password` = '%s' LIMIT 1",
dbesc($username),
dbesc($new_password_encoded)
);
if (DBM::is_result($r)) {
$u = $r[0];
$newuid = intval($r[0]['uid']);
}
}
else {
$result['message'] .= t('An error occurred during registration. Please try again.') . EOL ;
return $result;
}
/**
* if somebody clicked submit twice very quickly, they could end up with two accounts
* due to race condition. Remove this one.
*/
$r = q("SELECT `uid` FROM `user`
WHERE `nickname` = '%s' ",
dbesc($nickname)
);
if ((DBM::is_result($r)) && (count($r) > 1) && $newuid) {
$result['message'] .= t('Nickname is already registered. Please choose another.') . EOL;
dba::delete('user', array('uid' => $newuid));
return $result;
}
if(x($newuid) !== false) {
$r = q("INSERT INTO `profile` ( `uid`, `profile-name`, `is-default`, `name`, `photo`, `thumb`, `publish`, `net-publish` )
VALUES ( %d, '%s', %d, '%s', '%s', '%s', %d, %d ) ",
intval($newuid),
t('default'),
1,
dbesc($username),
dbesc(System::baseUrl() . "/photo/profile/{$newuid}.jpg"),
dbesc(System::baseUrl() . "/photo/avatar/{$newuid}.jpg"),
intval($publish),
intval($netpublish)
);
if ($r === false) {
$result['message'] .= t('An error occurred creating your default profile. Please try again.') . EOL;
// Start fresh next time.
dba::delete('user', array('uid' => $newuid));
return $result;
}
// Create the self contact
user_create_self_contact($newuid);
// Create a group with no members. This allows somebody to use it
// right away as a default group for new contacts.
require_once('include/group.php');
group_add($newuid, t('Friends'));
$r = q("SELECT `id` FROM `group` WHERE `uid` = %d AND `name` = '%s'",
intval($newuid),
dbesc(t('Friends'))
);
if (DBM::is_result($r)) {
$def_gid = $r[0]['id'];
q("UPDATE `user` SET `def_gid` = %d WHERE `uid` = %d",
intval($r[0]['id']),
intval($newuid)
);
}
if(Config::get('system', 'newuser_private') && $def_gid) {
q("UPDATE `user` SET `allow_gid` = '%s' WHERE `uid` = %d",
dbesc("<" . $def_gid . ">"),
intval($newuid)
);
}
}
// if we have no OpenID photo try to look up an avatar
if(! strlen($photo))
$photo = avatar_img($email);
// unless there is no avatar-plugin loaded
if (strlen($photo)) {
$photo_failure = false;
$filename = basename($photo);
$img_str = fetch_url($photo, true);
// guess mimetype from headers or filename
$type = Photo::guessImageType($photo, true);
$img = new Photo($img_str, $type);
if ($img->isValid()) {
$img->scaleImageSquare(175);
$hash = photo_new_resource();
$r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 4);
if ($r === false) {
$photo_failure = true;
}
$img->scaleImage(80);
$r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 5 );
if ($r === false) {
$photo_failure = true;
}
$img->scaleImage(48);
$r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 6 );
if ($r === false) {
$photo_failure = true;
}
if (! $photo_failure) {
q("UPDATE `photo` SET `profile` = 1 WHERE `resource-id` = '%s' ",
dbesc($hash)
);
}
}
}
call_hooks('register_account', $newuid);
$result['success'] = true;
$result['user'] = $u;
return $result;
}
/**
* @brief create the "self" contact from data from the user table
*
* @param integer $uid
*/
function user_create_self_contact($uid) {
// Only create the entry if it doesn't exist yet
$r = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `self`", intval($uid));
if (DBM::is_result($r)) {
return;
}
$r = q("SELECT `uid`, `username`, `nickname` FROM `user` WHERE `uid` = %d", intval($uid));
if (!DBM::is_result($r)) {
return;
}
$user = $r[0];
q("INSERT INTO `contact` (`uid`, `created`, `self`, `name`, `nick`, `photo`, `thumb`, `micro`, `blocked`, `pending`, `url`, `nurl`,
`addr`, `request`, `notify`, `poll`, `confirm`, `poco`, `name-date`, `uri-date`, `avatar-date`, `closeness`)
VALUES (%d, '%s', 1, '%s', '%s', '%s', '%s', '%s', 0, 0, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 0)",
intval($user['uid']),
datetime_convert(),
dbesc($user['username']),
dbesc($user['nickname']),
dbesc(System::baseUrl()."/photo/profile/".$user['uid'].".jpg"),
dbesc(System::baseUrl()."/photo/avatar/".$user['uid'].".jpg"),
dbesc(System::baseUrl()."/photo/micro/".$user['uid'].".jpg"),
dbesc(System::baseUrl()."/profile/".$user['nickname']),
dbesc(normalise_link(System::baseUrl()."/profile/".$user['nickname'])),
dbesc($user['nickname'].'@'.substr(System::baseUrl(), strpos(System::baseUrl(),'://') + 3)),
dbesc(System::baseUrl()."/dfrn_request/".$user['nickname']),
dbesc(System::baseUrl()."/dfrn_notify/".$user['nickname']),
dbesc(System::baseUrl()."/dfrn_poll/".$user['nickname']),
dbesc(System::baseUrl()."/dfrn_confirm/".$user['nickname']),
dbesc(System::baseUrl()."/poco/".$user['nickname']),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc(datetime_convert())
);
}
/**
* @brief send registration confiŕmation with the intormation that reg is pending
*
* @param string $email
* @param string $sitename
* @param string $username
* @return NULL|boolean from notification() and email() inherited
*/
function send_register_pending_eml($email, $sitename, $username) {
$body = deindent(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);
return notification(array(
'type' => SYSTEM_EMAIL,
'to_email' => $email,
'subject'=> sprintf( t('Registration at %s'), $sitename),
'body' => $body));
}
/*
* send registration confirmation.
* It's here as a function because the mail is sent
* from different parts
*/
function send_register_open_eml($email, $sitename, $siteurl, $username, $password){
$preamble = deindent(t('
Dear %1$s,
Thank you for registering at %2$s. Your account has been created.
'));
$body = deindent(t('
The login details are as follows:
Site Location: %3$s
Login Name: %1$s
Password: %5$s
You may change your password from your account "Settings" page after logging
in.
Please take a few moments to review the other account settings on that page.
You may also wish to add some basic information to your default profile
(on the "Profiles" page) so that other people can easily find you.
We recommend setting your full name, adding a profile photo,
adding some profile "keywords" (very useful in making new friends) - and
perhaps what country you live in; if you do not wish to be more specific
than that.
We fully respect your right to privacy, and none of these items are necessary.
If you are new and do not know anybody here, they may help
you to make some new and interesting friends.
Thank you and welcome to %2$s.'));
$preamble = sprintf($preamble, $username, $sitename);
$body = sprintf($body, $email, $sitename, $siteurl, $username, $password);
return notification(array(
'type' => SYSTEM_EMAIL,
'to_email' => $email,
'subject'=> sprintf( t('Registration details for %s'), $sitename),
'preamble'=> $preamble,
'body' => $body));
}

View file

@ -1,11 +1,11 @@
<?php <?php
/** /**
* @file mod/admin.php * @file mod/admin.php
* *
* @brief Friendica admin * @brief Friendica admin
*/ */
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\Worker; use Friendica\Core\Worker;
@ -1466,9 +1466,7 @@ function admin_page_users_post(App $a)
check_form_security_token_redirectOnErr('/admin/users', 'admin_users'); check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
if (!($nu_name === "") && !($nu_email === "") && !($nu_nickname === "")) { if (!($nu_name === "") && !($nu_email === "") && !($nu_nickname === "")) {
require_once 'include/user.php'; $result = User::create(array('username' => $nu_name, 'email' => $nu_email,
$result = create_user(array('username' => $nu_name, 'email' => $nu_email,
'nickname' => $nu_nickname, 'verified' => 1, 'language' => $nu_language)); 'nickname' => $nu_nickname, 'verified' => 1, 'language' => $nu_language));
if (!$result['success']) { if (!$result['success']) {
notice($result['message']); notice($result['message']);
@ -2293,7 +2291,7 @@ function admin_page_features_post(App $a)
logger('postvars: ' . print_r($_POST, true), LOGGER_DATA); logger('postvars: ' . print_r($_POST, true), LOGGER_DATA);
$arr = array(); $arr = array();
$features = get_features(false); $features = Feature::get(false);
foreach ($features as $fname => $fdata) { foreach ($features as $fname => $fdata) {
foreach (array_slice($fdata, 1) as $f) { foreach (array_slice($fdata, 1) as $f) {
@ -2338,7 +2336,7 @@ function admin_page_features(App $a)
{ {
if ((argc() > 1) && (argv(1) === 'features')) { if ((argc() > 1) && (argv(1) === 'features')) {
$arr = array(); $arr = array();
$features = get_features(false); $features = Feature::get(false);
foreach ($features as $fname => $fdata) { foreach ($features as $fname => $fdata) {
$arr[$fname] = array(); $arr[$fname] = array();

View file

@ -5,8 +5,8 @@
* This calendar is for profile visitors and contains only the events * This calendar is for profile visitors and contains only the events
* of the profile owner * of the profile owner
*/ */
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
use Friendica\Core\System; use Friendica\Core\System;
@ -301,7 +301,7 @@ function cal_content(App $a) {
// Test permissions // Test permissions
// Respect the export feature setting for all other /cal pages if it's not the own profile // Respect the export feature setting for all other /cal pages if it's not the own profile
if( ((local_user() !== intval($owner_uid))) && ! feature_enabled($owner_uid, "export_calendar")) { if( ((local_user() !== intval($owner_uid))) && ! Feature::isEnabled($owner_uid, "export_calendar")) {
notice( t('Permission denied.') . EOL); notice( t('Permission denied.') . EOL);
goaway('cal/' . $nick); goaway('cal/' . $nick);
} }

View file

@ -1,6 +1,9 @@
<?php <?php
/**
* @file mod/editpost.php
*/
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Database\DBM; use Friendica\Database\DBM;
@ -131,7 +134,7 @@ function editpost_content(App $a) {
'$title' => htmlspecialchars($itm[0]['title']), '$title' => htmlspecialchars($itm[0]['title']),
'$placeholdertitle' => t('Set title'), '$placeholdertitle' => t('Set title'),
'$category' => file_tag_file_to_list($itm[0]['file'], 'category'), '$category' => file_tag_file_to_list($itm[0]['file'], 'category'),
'$placeholdercategory' => (feature_enabled(local_user(),'categories') ? t('Categories (comma-separated list)') : ''), '$placeholdercategory' => (Feature::isEnabled(local_user(),'categories') ? t('Categories (comma-separated list)') : ''),
'$emtitle' => t('Example: bob@example.com, mary@example.com'), '$emtitle' => t('Example: bob@example.com, mary@example.com'),
'$lockstate' => $lockstate, '$lockstate' => $lockstate,
'$acl' => '', // populate_acl((($group) ? $group_acl : $a->user)), '$acl' => '', // populate_acl((($group) ? $group_acl : $a->user)),

View file

@ -3,6 +3,7 @@
* @file mod/network.php * @file mod/network.php
*/ */
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Content\ForumManager; use Friendica\Content\ForumManager;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Core\Config; use Friendica\Core\Config;
@ -156,8 +157,8 @@ function network_init(App $a) {
$a->page['aside'] = ''; $a->page['aside'] = '';
} }
$a->page['aside'] .= (feature_enabled(local_user(),'groups') ? group_side('network/0','network','standard',$group_id) : ''); $a->page['aside'] .= (Feature::isEnabled(local_user(),'groups') ? group_side('network/0','network','standard',$group_id) : '');
$a->page['aside'] .= (feature_enabled(local_user(), 'forumlist_widget') ? ForumManager::widget(local_user(), $cid) : ''); $a->page['aside'] .= (Feature::isEnabled(local_user(), 'forumlist_widget') ? ForumManager::widget(local_user(), $cid) : '');
$a->page['aside'] .= posted_date_widget('network',local_user(),false); $a->page['aside'] .= posted_date_widget('network',local_user(),false);
$a->page['aside'] .= networks_widget('network',(x($_GET, 'nets') ? $_GET['nets'] : '')); $a->page['aside'] .= networks_widget('network',(x($_GET, 'nets') ? $_GET['nets'] : ''));
$a->page['aside'] .= saved_searches($search); $a->page['aside'] .= saved_searches($search);
@ -166,7 +167,7 @@ function network_init(App $a) {
function saved_searches($search) { function saved_searches($search) {
if (!feature_enabled(local_user(),'savedsearch')) { if (!Feature::isEnabled(local_user(),'savedsearch')) {
return ''; return '';
} }
@ -918,7 +919,7 @@ function network_tabs(App $a)
), ),
); );
if (feature_enabled(local_user(),'personal_tab')) { if (Feature::isEnabled(local_user(),'personal_tab')) {
$tabs[] = array( $tabs[] = array(
'label' => t('Personal'), 'label' => t('Personal'),
'url' => str_replace('/new', '', $cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '/?f=') . '&conv=1', 'url' => str_replace('/new', '', $cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '/?f=') . '&conv=1',
@ -929,7 +930,7 @@ function network_tabs(App $a)
); );
} }
if (feature_enabled(local_user(),'new_tab')) { if (Feature::isEnabled(local_user(),'new_tab')) {
$tabs[] = array( $tabs[] = array(
'label' => t('New'), 'label' => t('New'),
'url' => 'network/new' . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : ''), 'url' => 'network/new' . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : ''),
@ -940,7 +941,7 @@ function network_tabs(App $a)
); );
} }
if (feature_enabled(local_user(),'link_tab')) { if (Feature::isEnabled(local_user(),'link_tab')) {
$tabs[] = array( $tabs[] = array(
'label' => t('Shared Links'), 'label' => t('Shared Links'),
'url' => str_replace('/new', '', $cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '/?f=') . '&bmark=1', 'url' => str_replace('/new', '', $cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '/?f=') . '&bmark=1',
@ -951,7 +952,7 @@ function network_tabs(App $a)
); );
} }
if (feature_enabled(local_user(),'star_posts')) { if (Feature::isEnabled(local_user(),'star_posts')) {
$tabs[] = array( $tabs[] = array(
'label' => t('Starred'), 'label' => t('Starred'),
'url' => str_replace('/new', '', $cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '/?f=') . '&star=1', 'url' => str_replace('/new', '', $cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '/?f=') . '&star=1',

View file

@ -3,6 +3,7 @@
* @file mod/photos.php * @file mod/photos.php
*/ */
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\Worker; use Friendica\Core\Worker;
@ -895,7 +896,7 @@ function photos_post(App $a) {
/// @TODO merge these 2 if() into one? /// @TODO merge these 2 if() into one?
if ($exif && $exif['GPS']) { if ($exif && $exif['GPS']) {
if (feature_enabled($channel_id,'photo_location')) { if (Feature::isEnabled($channel_id,'photo_location')) {
$lat = getGps($exif['GPS']['GPSLatitude'], $exif['GPS']['GPSLatitudeRef']); $lat = getGps($exif['GPS']['GPSLatitude'], $exif['GPS']['GPSLatitudeRef']);
$lon = getGps($exif['GPS']['GPSLongitude'], $exif['GPS']['GPSLongitudeRef']); $lon = getGps($exif['GPS']['GPSLongitude'], $exif['GPS']['GPSLongitudeRef']);
} }
@ -1584,7 +1585,7 @@ function photos_content(App $a) {
$likebuttons = replace_macros($like_tpl, array( $likebuttons = replace_macros($like_tpl, array(
'$id' => $link_item['id'], '$id' => $link_item['id'],
'$likethis' => t("I like this \x28toggle\x29"), '$likethis' => t("I like this \x28toggle\x29"),
'$nolike' => (feature_enabled(local_user(), 'dislike') ? t("I don't like this \x28toggle\x29") : ''), '$nolike' => (Feature::isEnabled(local_user(), 'dislike') ? t("I don't like this \x28toggle\x29") : ''),
'$wait' => t('Please wait'), '$wait' => t('Please wait'),
'$return_path' => $a->query_string, '$return_path' => $a->query_string,
)); ));
@ -1735,7 +1736,7 @@ function photos_content(App $a) {
$response_verbs = array('like'); $response_verbs = array('like');
if (feature_enabled($owner_uid, 'dislike')) { if (Feature::isEnabled($owner_uid, 'dislike')) {
$response_verbs[] = 'dislike'; $response_verbs[] = 'dislike';
} }
$responses = get_responses($conv_responses,$response_verbs, '', $link_item); $responses = get_responses($conv_responses,$response_verbs, '', $link_item);

View file

@ -3,6 +3,7 @@
* @file include/ping.php * @file include/ping.php
*/ */
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Content\ForumManager; use Friendica\Content\ForumManager;
use Friendica\Core\Cache; use Friendica\Core\Cache;
use Friendica\Core\System; use Friendica\Core\System;
@ -149,7 +150,7 @@ function ping_init(App $a)
} }
if ($network_count) { if ($network_count) {
if (intval(feature_enabled(local_user(), 'groups'))) { if (intval(Feature::isEnabled(local_user(), 'groups'))) {
// Find out how unseen network posts are spread across groups // Find out how unseen network posts are spread across groups
$group_counts = groups_count_unseen(); $group_counts = groups_count_unseen();
if (DBM::is_result($group_counts)) { if (DBM::is_result($group_counts)) {
@ -161,7 +162,7 @@ function ping_init(App $a)
} }
} }
if (intval(feature_enabled(local_user(), 'forumlist_widget'))) { if (intval(Feature::isEnabled(local_user(), 'forumlist_widget'))) {
$forum_counts = ForumManager::countUnseenItems(); $forum_counts = ForumManager::countUnseenItems();
if (DBM::is_result($forums_counts)) { if (DBM::is_result($forums_counts)) {
foreach ($forums_counts as $forum_count) { foreach ($forums_counts as $forum_count) {

View file

@ -3,6 +3,7 @@
* @file mod/profiles.php * @file mod/profiles.php
*/ */
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
use Friendica\Core\System; use Friendica\Core\System;
@ -673,10 +674,10 @@ function profiles_content(App $a) {
array(t('No'), t('Yes')) //Off - On strings array(t('No'), t('Yes')) //Off - On strings
), ),
'$multi_profiles' => feature_enabled(local_user(), 'multi_profiles'), '$multi_profiles' => Feature::isEnabled(local_user(), 'multi_profiles'),
'$form_security_token' => get_form_security_token("profile_edit"), '$form_security_token' => get_form_security_token("profile_edit"),
'$form_security_token_photo' => get_form_security_token("profile_photo"), '$form_security_token_photo' => get_form_security_token("profile_photo"),
'$profile_clone_link' => ((feature_enabled(local_user(), 'multi_profiles')) ? 'profiles/clone/' . $r[0]['id'] . '?t=' . get_form_security_token("profile_clone") : ""), '$profile_clone_link' => ((Feature::isEnabled(local_user(), 'multi_profiles')) ? 'profiles/clone/' . $r[0]['id'] . '?t=' . get_form_security_token("profile_clone") : ""),
'$profile_drop_link' => 'profiles/drop/' . $r[0]['id'] . '?t=' . get_form_security_token("profile_drop"), '$profile_drop_link' => 'profiles/drop/' . $r[0]['id'] . '?t=' . get_form_security_token("profile_drop"),
'$profile_action' => t('Profile Actions'), '$profile_action' => t('Profile Actions'),
@ -754,7 +755,7 @@ function profiles_content(App $a) {
return $o; return $o;
} else { } else {
// If we don't support multi profiles, don't display this list. // If we don't support multi profiles, don't display this list.
if (!feature_enabled(local_user(), 'multi_profiles')) { if (!Feature::isEnabled(local_user(), 'multi_profiles')) {
$r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `is-default`=1", $r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `is-default`=1",
local_user() local_user()
); );

View file

@ -5,10 +5,10 @@ use Friendica\Core\Config;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Model\User;
require_once('include/enotify.php'); require_once 'include/enotify.php';
require_once('include/bbcode.php'); require_once 'include/bbcode.php';
require_once('include/user.php');
if(! function_exists('register_post')) { if(! function_exists('register_post')) {
function register_post(App $a) { function register_post(App $a) {
@ -61,7 +61,7 @@ function register_post(App $a) {
$arr['verified'] = $verified; $arr['verified'] = $verified;
$arr['language'] = get_browser_language(); $arr['language'] = get_browser_language();
$result = create_user($arr); $result = User::create($arr);
if(! $result['success']) { if(! $result['success']) {
notice($result['message']); notice($result['message']);
@ -89,7 +89,7 @@ function register_post(App $a) {
// Only send a password mail when the password wasn't manually provided // Only send a password mail when the password wasn't manually provided
if (!x($_POST,'password1') || !x($_POST,'confirm')) { if (!x($_POST,'password1') || !x($_POST,'confirm')) {
$res = send_register_open_eml( $res = User::sendRegisterOpenEmail(
$user['email'], $user['email'],
$a->config['sitename'], $a->config['sitename'],
System::baseUrl(), System::baseUrl(),
@ -159,7 +159,7 @@ function register_post(App $a) {
)); ));
} }
// send notification to the user, that the registration is pending // send notification to the user, that the registration is pending
send_register_pending_eml( User::sendRegisterPendingEmail(
$user['email'], $user['email'],
$a->config['sitename'], $a->config['sitename'],
$user['username']); $user['username']);

View file

@ -6,11 +6,10 @@ use Friendica\Core\System;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\DBM; use Friendica\Database\DBM;
require_once('include/enotify.php'); require_once 'include/enotify.php';
require_once('include/user.php');
function user_allow($hash) {
function user_allow($hash)
{
$a = get_app(); $a = get_app();
$register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1", $register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1",
@ -18,7 +17,7 @@ function user_allow($hash) {
); );
if (! DBM::is_result($register)) { if (!DBM::is_result($register)) {
return false; return false;
} }
@ -26,7 +25,7 @@ function user_allow($hash) {
intval($register[0]['uid']) intval($register[0]['uid'])
); );
if (! DBM::is_result($user)) { if (!DBM::is_result($user)) {
killme(); killme();
} }
@ -44,14 +43,14 @@ function user_allow($hash) {
); );
if (DBM::is_result($r) && $r[0]['net-publish']) { if (DBM::is_result($r) && $r[0]['net-publish']) {
$url = System::baseUrl() . '/profile/' . $user[0]['nickname']; $url = System::baseUrl() . '/profile/' . $user[0]['nickname'];
if ($url && strlen(Config::get('system','directory'))) { if ($url && strlen(Config::get('system', 'directory'))) {
Worker::add(PRIORITY_LOW, "Directory", $url); Worker::add(PRIORITY_LOW, "Directory", $url);
} }
} }
push_lang($register[0]['language']); push_lang($register[0]['language']);
send_register_open_eml( User::sendRegisterOpenEmail(
$user[0]['email'], $user[0]['email'],
$a->config['sitename'], $a->config['sitename'],
System::baseUrl(), System::baseUrl(),
@ -60,20 +59,17 @@ function user_allow($hash) {
pop_lang(); pop_lang();
if($res) { if ($res) {
info( t('Account approved.') . EOL ); info(t('Account approved.') . EOL);
return true; return true;
} }
} }
// This does not have to go through user_remove() and save the nickname // This does not have to go through user_remove() and save the nickname
// permanently against re-registration, as the person was not yet // permanently against re-registration, as the person was not yet
// allowed to have friends on this system // allowed to have friends on this system
function user_deny($hash)
function user_deny($hash) { {
$register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1", $register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1",
dbesc($hash) dbesc($hash)
); );
@ -91,23 +87,22 @@ function user_deny($hash) {
notice(sprintf(t('Registration revoked for %s'), $user[0]['username']) . EOL); notice(sprintf(t('Registration revoked for %s'), $user[0]['username']) . EOL);
return true; return true;
} }
function regmod_content(App $a) { function regmod_content(App $a)
{
global $lang; global $lang;
$_SESSION['return_url'] = $a->cmd; $_SESSION['return_url'] = $a->cmd;
if (! local_user()) { if (!local_user()) {
info( t('Please login.') . EOL); info(t('Please login.') . EOL);
$o .= '<br /><br />' . login(($a->config['register_policy'] == REGISTER_CLOSED) ? 0 : 1); $o .= '<br /><br />' . login(($a->config['register_policy'] == REGISTER_CLOSED) ? 0 : 1);
return $o; return $o;
} }
if ((!is_site_admin()) || (x($_SESSION,'submanage') && intval($_SESSION['submanage']))) { if ((!is_site_admin()) || (x($_SESSION, 'submanage') && intval($_SESSION['submanage']))) {
notice( t('Permission denied.') . EOL); notice(t('Permission denied.') . EOL);
return ''; return '';
} }
@ -115,20 +110,18 @@ function regmod_content(App $a) {
killme(); killme();
} }
$cmd = $a->argv[1]; $cmd = $a->argv[1];
$hash = $a->argv[2]; $hash = $a->argv[2];
if ($cmd === 'deny') { if ($cmd === 'deny') {
user_deny($hash); user_deny($hash);
goaway(System::baseUrl()."/admin/users/"); goaway(System::baseUrl() . "/admin/users/");
killme(); killme();
} }
if ($cmd === 'allow') { if ($cmd === 'allow') {
user_allow($hash); user_allow($hash);
goaway(System::baseUrl()."/admin/users/"); goaway(System::baseUrl() . "/admin/users/");
killme(); killme();
} }
} }

View file

@ -1,20 +1,23 @@
<?php <?php
/**
* @file mod/search.php
*/
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\Cache; use Friendica\Core\Cache;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Database\DBM; use Friendica\Database\DBM;
require_once("include/bbcode.php"); require_once "include/bbcode.php";
require_once('include/security.php'); require_once 'include/security.php';
require_once('include/conversation.php'); require_once 'include/conversation.php';
require_once('mod/dirfind.php'); require_once 'mod/dirfind.php';
function search_saved_searches() { function search_saved_searches() {
$o = ''; $o = '';
if (! feature_enabled(local_user(),'savedsearch')) if (! Feature::isEnabled(local_user(),'savedsearch'))
return $o; return $o;
$r = q("SELECT `id`,`term` FROM `search` WHERE `uid` = %d", $r = q("SELECT `id`,`term` FROM `search` WHERE `uid` = %d",

View file

@ -3,6 +3,7 @@
* @file mod/settings.php * @file mod/settings.php
*/ */
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Core\Config; use Friendica\Core\Config;
@ -52,7 +53,7 @@ function settings_init(App $a) {
), ),
); );
if (get_features()) { if (Feature::get()) {
$tabs[] = array( $tabs[] = array(
'label' => t('Additional features'), 'label' => t('Additional features'),
'url' => 'settings/features', 'url' => 'settings/features',
@ -784,12 +785,12 @@ function settings_content(App $a) {
if (($a->argc > 1) && ($a->argv[1] === 'features')) { if (($a->argc > 1) && ($a->argv[1] === 'features')) {
$arr = array(); $arr = array();
$features = get_features(); $features = Feature::get();
foreach ($features as $fname => $fdata) { foreach ($features as $fname => $fdata) {
$arr[$fname] = array(); $arr[$fname] = array();
$arr[$fname][0] = $fdata[0]; $arr[$fname][0] = $fdata[0];
foreach (array_slice($fdata,1) as $f) { foreach (array_slice($fdata,1) as $f) {
$arr[$fname][1][] = array('feature_' .$f[0], $f[1],((intval(feature_enabled(local_user(), $f[0]))) ? "1" : ''), $f[2],array(t('Off'), t('On'))); $arr[$fname][1][] = array('feature_' .$f[0], $f[1],((intval(Feature::isEnabled(local_user(), $f[0]))) ? "1" : ''), $f[2],array(t('Off'), t('On')));
} }
} }

154
src/Content/Feature.php Normal file
View file

@ -0,0 +1,154 @@
<?php
/**
* @file src/Content/Feature.php
* @brief Features management
*/
namespace Friendica\Content;
use Friendica\Core\Config;
use Friendica\Core\PConfig;
require_once 'include/plugin.php';
class Feature
{
/**
* @brief check if feature is enabled
*
* @param integer $uid user id
* @param string $feature feature
* @return boolean
*/
public static function isEnabled($uid, $feature)
{
$x = Config::get('feature_lock', $feature, false);
if ($x === false) {
$x = PConfig::get($uid, 'feature', $feature, false);
}
if ($x === false) {
$x = Config::get('feature', $feature, false);
}
if ($x === false) {
$x = self::getDefault($feature);
}
$arr = array('uid' => $uid, 'feature' => $feature, 'enabled' => $x);
call_hooks('isEnabled', $arr);
return($arr['enabled']);
}
/**
* @brief check if feature is enabled or disabled by default
*
* @param string $feature feature
* @return boolean
*/
private static function getDefault($feature)
{
$f = self::get();
foreach ($f as $cat) {
foreach ($cat as $feat) {
if (is_array($feat) && $feat[0] === $feature) {
return $feat[3];
}
}
}
return false;
}
/**
* @brief Get a list of all available features
*
* The array includes the setting group, the setting name,
* explainations for the setting and if it's enabled or disabled
* by default
*
* @param bool $filtered True removes any locked features
*
* @return array
*/
public static function get($filtered = true)
{
$arr = array(
// General
'general' => array(
t('General Features'),
//array('expire', t('Content Expiration'), t('Remove old posts/comments after a period of time')),
array('multi_profiles', t('Multiple Profiles'), t('Ability to create multiple profiles'), false, Config::get('feature_lock', 'multi_profiles', false)),
array('photo_location', t('Photo Location'), t('Photo metadata is normally stripped. This extracts the location (if present) prior to stripping metadata and links it to a map.'), false, Config::get('feature_lock', 'photo_location', false)),
array('export_calendar', t('Export Public Calendar'), t('Ability for visitors to download the public calendar'), false, Config::get('feature_lock', 'export_calendar', false)),
),
// Post composition
'composition' => array(
t('Post Composition Features'),
array('preview', t('Post Preview'), t('Allow previewing posts and comments before publishing them'), false, Config::get('feature_lock', 'preview', false)),
array('aclautomention', t('Auto-mention Forums'), t('Add/remove mention when a forum page is selected/deselected in ACL window.'), false, Config::get('feature_lock', 'aclautomention', false)),
),
// Network sidebar widgets
'widgets' => array(
t('Network Sidebar Widgets'),
array('archives', t('Search by Date'), t('Ability to select posts by date ranges'), false, Config::get('feature_lock', 'archives', false)),
array('forumlist_widget', t('List Forums'), t('Enable widget to display the forums your are connected with'), true, Config::get('feature_lock', 'forumlist_widget', false)),
array('groups', t('Group Filter'), t('Enable widget to display Network posts only from selected group'), false, Config::get('feature_lock', 'groups', false)),
array('networks', t('Network Filter'), t('Enable widget to display Network posts only from selected network'), false, Config::get('feature_lock', 'networks', false)),
array('savedsearch', t('Saved Searches'), t('Save search terms for re-use'), false, Config::get('feature_lock', 'savedsearch', false)),
),
// Network tabs
'net_tabs' => array(
t('Network Tabs'),
array('personal_tab', t('Network Personal Tab'), t('Enable tab to display only Network posts that you\'ve interacted on'), false, Config::get('feature_lock', 'personal_tab', false)),
array('new_tab', t('Network New Tab'), t('Enable tab to display only new Network posts (from the last 12 hours)'), false, Config::get('feature_lock', 'new_tab', false)),
array('link_tab', t('Network Shared Links Tab'), t('Enable tab to display only Network posts with links in them'), false, Config::get('feature_lock', 'link_tab', false)),
),
// Item tools
'tools' => array(
t('Post/Comment Tools'),
array('multi_delete', t('Multiple Deletion'), t('Select and delete multiple posts/comments at once'), false, Config::get('feature_lock', 'multi_delete', false)),
array('edit_posts', t('Edit Sent Posts'), t('Edit and correct posts and comments after sending'), false, Config::get('feature_lock', 'edit_posts', false)),
array('commtag', t('Tagging'), t('Ability to tag existing posts'), false, Config::get('feature_lock', 'commtag', false)),
array('categories', t('Post Categories'), t('Add categories to your posts'), false, Config::get('feature_lock', 'categories', false)),
array('filing', t('Saved Folders'), t('Ability to file posts under folders'), false, Config::get('feature_lock', 'filing', false)),
array('dislike', t('Dislike Posts'), t('Ability to dislike posts/comments'), false, Config::get('feature_lock', 'dislike', false)),
array('star_posts', t('Star Posts'), t('Ability to mark special posts with a star indicator'), false, Config::get('feature_lock', 'star_posts', false)),
array('ignore_posts', t('Mute Post Notifications'), t('Ability to mute notifications for a thread'), false, Config::get('feature_lock', 'ignore_posts', false)),
),
// Advanced Profile Settings
'advanced_profile' => array(
t('Advanced Profile Settings'),
array('forumlist_profile', t('List Forums'), t('Show visitors public community forums at the Advanced Profile Page'), false, Config::get('feature_lock', 'forumlist_profile', false)),
array('tagadelic', t('Tag Cloud'), t('Provide a personal tag cloud on your profile page'), false, Config::get('feature_lock', 'tagadelic', false)),
),
);
// removed any locked features and remove the entire category if this makes it empty
if ($filtered) {
foreach ($arr as $k => $x) {
$has_items = false;
$kquantity = count($arr[$k]);
for ($y = 0; $y < $kquantity; $y ++) {
if (is_array($arr[$k][$y])) {
if ($arr[$k][$y][4] === false) {
$has_items = true;
} else {
unset($arr[$k][$y]);
}
}
}
if (! $has_items) {
unset($arr[$k]);
}
}
}
call_hooks('get', $arr);
return $arr;
}
}

View file

@ -6,6 +6,7 @@
namespace Friendica\Content; namespace Friendica\Content;
use Friendica\App; use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Database\DBM; use Friendica\Database\DBM;
use dba; use dba;
@ -82,7 +83,7 @@ class ForumManager
*/ */
public static function widget($uid, $cid = 0) public static function widget($uid, $cid = 0)
{ {
if (! intval(feature_enabled(local_user(), 'forumlist_widget'))) { if (! intval(Feature::isEnabled(local_user(), 'forumlist_widget'))) {
return; return;
} }
@ -141,7 +142,7 @@ class ForumManager
*/ */
public static function profileAdvanced($uid) public static function profileAdvanced($uid)
{ {
$profile = intval(feature_enabled($uid, 'forumlist_profile')); $profile = intval(Feature::isEnabled($uid, 'forumlist_profile'));
if (! $profile) { if (! $profile) {
return; return;
} }

View file

@ -7,19 +7,41 @@
namespace Friendica\Model; namespace Friendica\Model;
use Friendica\Core\Config;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\DBM; use Friendica\Database\DBM;
use Friendica\Object\Contact;
use Friendica\Object\Photo;
use dba; use dba;
require_once 'boot.php'; require_once 'boot.php';
require_once 'include/crypto.php';
require_once 'include/enotify.php';
require_once 'include/group.php';
require_once 'include/network.php';
require_once 'library/openid.php';
require_once 'include/pgettext.php';
require_once 'include/plugin.php'; require_once 'include/plugin.php';
require_once 'include/text.php';
/** /**
* @brief This class handles User related functions * @brief This class handles User related functions
*/ */
class User class User
{ {
/**
* @brief Authenticate a user with a clear text password
*
* User info can be any of the following:
* - User DB object
* - User Id
* - User email or username or nickname
* - User array with at least the uid and the hashed password
*
* @param mixed $user_info
* @param string $password
* @return boolean
*/
public static function authenticate($user_info, $password) public static function authenticate($user_info, $password)
{ {
if (is_object($user_info)) { if (is_object($user_info)) {
@ -66,6 +88,424 @@ class User
return $user['uid']; return $user['uid'];
} }
/**
* @brief Catch-all user creation function
*
* Creates a user from the provided data array, either form fields or OpenID.
* Required: { username, nickname, email } or { openid_url }
*
* Performs the following:
* - Sends to the OpenId auth URL (if relevant)
* - Creates new key pairs for crypto
* - Create self-contact
* - Create profile image
*
* @param array $data
* @return string
*/
public static function create(array $data)
{
$a = get_app();
$result = array('success' => false, 'user' => null, 'password' => '', 'message' => '');
$using_invites = Config::get('system', 'invitation_only');
$num_invites = Config::get('system', 'number_invites');
$invite_id = x($data, 'invite_id') ? notags(trim($data['invite_id'])) : '';
$username = x($data, 'username') ? notags(trim($data['username'])) : '';
$nickname = x($data, 'nickname') ? notags(trim($data['nickname'])) : '';
$email = x($data, 'email') ? notags(trim($data['email'])) : '';
$openid_url = x($data, 'openid_url') ? notags(trim($data['openid_url'])) : '';
$photo = x($data, 'photo') ? notags(trim($data['photo'])) : '';
$password = x($data, 'password') ? trim($data['password']) : '';
$password1 = x($data, 'password1') ? trim($data['password1']) : '';
$confirm = x($data, 'confirm') ? trim($data['confirm']) : '';
$blocked = x($data, 'blocked') ? intval($data['blocked']) : 0;
$verified = x($data, 'verified') ? intval($data['verified']) : 0;
$publish = x($data, 'profile_publish_reg') && intval($data['profile_publish_reg']) ? 1 : 0;
$netpublish = strlen(Config::get('system', 'directory')) ? $publish : 0;
if ($password1 != $confirm) {
$result['message'] .= t('Passwords do not match. Password unchanged.') . EOL;
return $result;
} elseif ($password1 != "") {
$password = $password1;
}
$tmp_str = $openid_url;
if ($using_invites) {
if (!$invite_id) {
$result['message'] .= t('An invitation is required.') . EOL;
return $result;
}
$r = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1", dbesc($invite_id));
if (!results($r)) {
$result['message'] .= t('Invitation could not be verified.') . EOL;
return $result;
}
}
if (!x($username) || !x($email) || !x($nickname)) {
if ($openid_url) {
if (!validate_url($tmp_str)) {
$result['message'] .= t('Invalid OpenID url') . EOL;
return $result;
}
$_SESSION['register'] = 1;
$_SESSION['openid'] = $openid_url;
$openid = new LightOpenID;
$openid->identity = $openid_url;
$openid->returnUrl = System::baseUrl() . '/openid';
$openid->required = array('namePerson/friendly', 'contact/email', 'namePerson');
$openid->optional = array('namePerson/first', 'media/image/aspect11', 'media/image/default');
try {
$authurl = $openid->authUrl();
} catch (Exception $e) {
$result['message'] .= t("We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.") . EOL . EOL . t("The error message was:") . $e->getMessage() . EOL;
return $result;
}
goaway($authurl);
// NOTREACHED
}
notice(t('Please enter the required information.') . EOL);
return;
}
if (!validate_url($tmp_str)) {
$openid_url = '';
}
$err = '';
// collapse multiple spaces in name
$username = preg_replace('/ +/', ' ', $username);
if (mb_strlen($username) > 48) {
$result['message'] .= t('Please use a shorter name.') . EOL;
}
if (mb_strlen($username) < 3) {
$result['message'] .= t('Name too short.') . EOL;
}
// So now we are just looking for a space in the full name.
$loose_reg = Config::get('system', 'no_regfullname');
if (!$loose_reg) {
$username = mb_convert_case($username, MB_CASE_TITLE, 'UTF-8');
if (!strpos($username, ' ')) {
$result['message'] .= t("That doesn't appear to be your full \x28First Last\x29 name.") . EOL;
}
}
if (!allowed_email($email)) {
$result['message'] .= t('Your email domain is not among those allowed on this site.') . EOL;
}
if (!valid_email($email) || !validate_email($email)) {
$result['message'] .= t('Not a valid email address.') . EOL;
}
// Disallow somebody creating an account using openid that uses the admin email address,
// since openid bypasses email verification. We'll allow it if there is not yet an admin account.
$adminlist = explode(",", str_replace(" ", "", strtolower($a->config['admin_email'])));
//if((x($a->config,'admin_email')) && (strcasecmp($email,$a->config['admin_email']) == 0) && strlen($openid_url)) {
if (x($a->config, 'admin_email') && in_array(strtolower($email), $adminlist) && strlen($openid_url)) {
$r = q("SELECT * FROM `user` WHERE `email` = '%s' LIMIT 1",
dbesc($email)
);
if (DBM::is_result($r)) {
$result['message'] .= t('Cannot use that email.') . EOL;
}
}
$nickname = $data['nickname'] = strtolower($nickname);
if (!preg_match("/^[a-z0-9][a-z0-9\_]*$/", $nickname)) {
$result['message'] .= t('Your "nickname" can only contain "a-z", "0-9" and "_".') . EOL;
}
$r = q("SELECT `uid` FROM `user`
WHERE `nickname` = '%s' LIMIT 1",
dbesc($nickname)
);
if (DBM::is_result($r)) {
$result['message'] .= t('Nickname is already registered. Please choose another.') . EOL;
}
// Check deleted accounts that had this nickname. Doesn't matter to us,
// but could be a security issue for federated platforms.
$r = q("SELECT * FROM `userd`
WHERE `username` = '%s' LIMIT 1",
dbesc($nickname)
);
if (DBM::is_result($r)) {
$result['message'] .= t('Nickname was once registered here and may not be re-used. Please choose another.') . EOL;
}
if (strlen($result['message'])) {
return $result;
}
$new_password = strlen($password) ? $password : autoname(6) . mt_rand(100, 9999);
$new_password_encoded = hash('whirlpool', $new_password);
$result['password'] = $new_password;
$keys = new_keypair(4096);
if ($keys === false) {
$result['message'] .= t('SERIOUS ERROR: Generation of security keys failed.') . EOL;
return $result;
}
$prvkey = $keys['prvkey'];
$pubkey = $keys['pubkey'];
// Create another keypair for signing/verifying salmon protocol messages.
$sres = new_keypair(512);
$sprvkey = $sres['prvkey'];
$spubkey = $sres['pubkey'];
$r = q("INSERT INTO `user` (`guid`, `username`, `password`, `email`, `openid`, `nickname`,
`pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked`, `timezone`, `default-location`)
VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, 'UTC', '')",
dbesc(generate_user_guid()),
dbesc($username),
dbesc($new_password_encoded),
dbesc($email),
dbesc($openid_url),
dbesc($nickname),
dbesc($pubkey),
dbesc($prvkey),
dbesc($spubkey),
dbesc($sprvkey),
dbesc(datetime_convert()),
intval($verified),
intval($blocked)
);
if ($r) {
$r = q("SELECT * FROM `user`
WHERE `username` = '%s' AND `password` = '%s' LIMIT 1",
dbesc($username),
dbesc($new_password_encoded)
);
if (DBM::is_result($r)) {
$u = $r[0];
$newuid = intval($r[0]['uid']);
}
} else {
$result['message'] .= t('An error occurred during registration. Please try again.') . EOL;
return $result;
}
/**
* if somebody clicked submit twice very quickly, they could end up with two accounts
* due to race condition. Remove this one.
*/
$r = q("SELECT `uid` FROM `user`
WHERE `nickname` = '%s' ",
dbesc($nickname)
);
if (DBM::is_result($r) && count($r) > 1 && $newuid) {
$result['message'] .= t('Nickname is already registered. Please choose another.') . EOL;
dba::delete('user', array('uid' => $newuid));
return $result;
}
if (x($newuid) !== false) {
$r = q("INSERT INTO `profile` ( `uid`, `profile-name`, `is-default`, `name`, `photo`, `thumb`, `publish`, `net-publish` )
VALUES ( %d, '%s', %d, '%s', '%s', '%s', %d, %d ) ",
intval($newuid),
t('default'),
1,
dbesc($username),
dbesc(System::baseUrl() . "/photo/profile/{$newuid}.jpg"),
dbesc(System::baseUrl() . "/photo/avatar/{$newuid}.jpg"),
intval($publish),
intval($netpublish)
);
if ($r === false) {
$result['message'] .= t('An error occurred creating your default profile. Please try again.') . EOL;
// Start fresh next time.
dba::delete('user', array('uid' => $newuid));
return $result;
}
// Create the self contact
Contact::createSelfFromUserId($newuid);
// Create a group with no members. This allows somebody to use it
// right away as a default group for new contacts.
group_add($newuid, t('Friends'));
$r = q("SELECT `id` FROM `group` WHERE `uid` = %d AND `name` = '%s'",
intval($newuid),
dbesc(t('Friends'))
);
if (DBM::is_result($r)) {
$def_gid = $r[0]['id'];
q("UPDATE `user` SET `def_gid` = %d WHERE `uid` = %d",
intval($r[0]['id']),
intval($newuid)
);
}
if (Config::get('system', 'newuser_private') && $def_gid) {
q("UPDATE `user` SET `allow_gid` = '%s' WHERE `uid` = %d",
dbesc("<" . $def_gid . ">"),
intval($newuid)
);
}
}
// if we have no OpenID photo try to look up an avatar
if (!strlen($photo)) {
$photo = avatar_img($email);
}
// unless there is no avatar-plugin loaded
if (strlen($photo)) {
$photo_failure = false;
$filename = basename($photo);
$img_str = fetch_url($photo, true);
// guess mimetype from headers or filename
$type = Photo::guessImageType($photo, true);
$img = new Photo($img_str, $type);
if ($img->isValid()) {
$img->scaleImageSquare(175);
$hash = photo_new_resource();
$r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 4);
if ($r === false) {
$photo_failure = true;
}
$img->scaleImage(80);
$r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 5);
if ($r === false) {
$photo_failure = true;
}
$img->scaleImage(48);
$r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 6);
if ($r === false) {
$photo_failure = true;
}
if (!$photo_failure) {
q("UPDATE `photo` SET `profile` = 1 WHERE `resource-id` = '%s' ",
dbesc($hash)
);
}
}
}
call_hooks('register_account', $newuid);
$result['success'] = true;
$result['user'] = $u;
return $result;
}
/**
* @brief Sends pending registration confiŕmation email
*
* @param string $email
* @param string $sitename
* @param string $username
* @return NULL|boolean from notification() and email() inherited
*/
public static function sendRegisterPendingEmail($email, $sitename, $username)
{
$body = deindent(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);
return notification(array(
'type' => SYSTEM_EMAIL,
'to_email' => $email,
'subject'=> sprintf( t('Registration at %s'), $sitename),
'body' => $body));
}
/**
* @brief Sends registration confirmation
*
* It's here as a function because the mail is sent from different parts
*
* @param string $email
* @param string $sitename
* @param string $siteurl
* @param string $username
* @param string $password
* @return NULL|boolean from notification() and email() inherited
*/
public static function sendRegisterOpenEmail($email, $sitename, $siteurl, $username, $password)
{
$preamble = deindent(t('
Dear %1$s,
Thank you for registering at %2$s. Your account has been created.
'));
$body = deindent(t('
The login details are as follows:
Site Location: %3$s
Login Name: %1$s
Password: %5$s
You may change your password from your account "Settings" page after logging
in.
Please take a few moments to review the other account settings on that page.
You may also wish to add some basic information to your default profile
(on the "Profiles" page) so that other people can easily find you.
We recommend setting your full name, adding a profile photo,
adding some profile "keywords" (very useful in making new friends) - and
perhaps what country you live in; if you do not wish to be more specific
than that.
We fully respect your right to privacy, and none of these items are necessary.
If you are new and do not know anybody here, they may help
you to make some new and interesting friends.
Thank you and welcome to %2$s.'));
$preamble = sprintf($preamble, $username, $sitename);
$body = sprintf($body, $email, $sitename, $siteurl, $username, $password);
return notification(array(
'type' => SYSTEM_EMAIL,
'to_email' => $email,
'subject'=> sprintf( t('Registration details for %s'), $sitename),
'preamble'=> $preamble,
'body' => $body));
}
/** /**
* @param object $uid user to remove * @param object $uid user to remove
* @return void * @return void

View file

@ -28,6 +28,52 @@ require_once 'include/text.php';
*/ */
class Contact extends BaseObject class Contact extends BaseObject
{ {
/**
* Creates the self-contact for the provided user id
*
* @param int $uid
* @return bool Operation success
*/
public static function createSelfFromUserId($uid)
{
// Only create the entry if it doesn't exist yet
if (dba::exists('contact', ['uid' => intval($uid), 'self'])) {
return true;
}
$user = dba::select('user', ['uid', 'username', 'nickname'], ['uid' => intval($uid)], ['limit' => 1]);
if (!DBM::is_result($user)) {
return false;
}
$return = dba::insert('contact', [
'uid' => $user['uid'],
'created' => datetime_convert(),
'self' => 1,
'name' => $user['username'],
'nick' => $user['nickname'],
'photo' => System::baseUrl() . '/photo/profile/' . $user['uid'] . '.jpg',
'thumb' => System::baseUrl() . '/photo/avatar/' . $user['uid'] . '.jpg',
'micro' => System::baseUrl() . '/photo/micro/' . $user['uid'] . '.jpg',
'blocked' => 0,
'pending' => 0,
'url' => System::baseUrl() . '/profile/' . $user['nickname'],
'nurl' => normalise_link(System::baseUrl() . '/profile/' . $user['nickname']),
'addr' => $user['nickname'] . '@' . substr(System::baseUrl(), strpos(System::baseUrl(), '://') + 3),
'request' => System::baseUrl() . '/dfrn_request/' . $user['nickname'],
'notify' => System::baseUrl() . '/dfrn_notify/' . $user['nickname'],
'poll' => System::baseUrl() . '/dfrn_poll/' . $user['nickname'],
'confirm' => System::baseUrl() . '/dfrn_confirm/' . $user['nickname'],
'poco' => System::baseUrl() . '/poco/' . $user['nickname'],
'name-date' => datetime_convert(),
'uri-date' => datetime_convert(),
'avatar-date' => datetime_convert(),
'closeness' => 0
]);
return $return;
}
/** /**
* @brief Marks a contact for removal * @brief Marks a contact for removal
* *

View file

@ -5,6 +5,7 @@
namespace Friendica\Object; namespace Friendica\Object;
use Friendica\BaseObject; use Friendica\BaseObject;
use Friendica\Content\Feature;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
use Friendica\Database\DBM; use Friendica\Database\DBM;
@ -161,7 +162,7 @@ class Item extends BaseObject
$drop = array( $drop = array(
'dropping' => $dropping, 'dropping' => $dropping,
'pagedrop' => ((feature_enabled($conv->getProfileOwner(), 'multi_delete')) ? $item['pagedrop'] : ''), 'pagedrop' => ((Feature::isEnabled($conv->getProfileOwner(), 'multi_delete')) ? $item['pagedrop'] : ''),
'select' => t('Select'), 'select' => t('Select'),
'delete' => t('Delete'), 'delete' => t('Delete'),
); );
@ -279,7 +280,7 @@ class Item extends BaseObject
} }
$tagger = ''; $tagger = '';
if (feature_enabled($conv->getProfileOwner(), 'commtag')) { if (Feature::isEnabled($conv->getProfileOwner(), 'commtag')) {
$tagger = array( $tagger = array(
'add' => t("add tag"), 'add' => t("add tag"),
'class' => "", 'class' => "",
@ -293,7 +294,7 @@ class Item extends BaseObject
if ($conv->isWritable()) { if ($conv->isWritable()) {
$buttons = array( $buttons = array(
'like' => array( t("I like this \x28toggle\x29"), t("like")), 'like' => array( t("I like this \x28toggle\x29"), t("like")),
'dislike' => ((feature_enabled($conv->getProfileOwner(), 'dislike')) ? array( t("I don't like this \x28toggle\x29"), t("dislike")) : ''), 'dislike' => ((Feature::isEnabled($conv->getProfileOwner(), 'dislike')) ? array( t("I don't like this \x28toggle\x29"), t("dislike")) : ''),
); );
if ($shareable) { if ($shareable) {
$buttons['share'] = array( t('Share this'), t('share')); $buttons['share'] = array( t('Share this'), t('share'));
@ -378,12 +379,12 @@ class Item extends BaseObject
'owner_photo' => $a->remove_baseurl(proxy_url($item['owner-thumb'], false, PROXY_SIZE_THUMB)), 'owner_photo' => $a->remove_baseurl(proxy_url($item['owner-thumb'], false, PROXY_SIZE_THUMB)),
'owner_name' => htmlentities($owner_name_e), 'owner_name' => htmlentities($owner_name_e),
'plink' => get_plink($item), 'plink' => get_plink($item),
'edpost' => ((feature_enabled($conv->getProfileOwner(), 'edit_posts')) ? $edpost : ''), 'edpost' => ((Feature::isEnabled($conv->getProfileOwner(), 'edit_posts')) ? $edpost : ''),
'isstarred' => $isstarred, 'isstarred' => $isstarred,
'star' => ((feature_enabled($conv->getProfileOwner(), 'star_posts')) ? $star : ''), 'star' => ((Feature::isEnabled($conv->getProfileOwner(), 'star_posts')) ? $star : ''),
'ignore' => ((feature_enabled($conv->getProfileOwner(), 'ignore_posts')) ? $ignore : ''), 'ignore' => ((Feature::isEnabled($conv->getProfileOwner(), 'ignore_posts')) ? $ignore : ''),
'tagger' => $tagger, 'tagger' => $tagger,
'filer' => ((feature_enabled($conv->getProfileOwner(), 'filing')) ? $filer : ''), 'filer' => ((Feature::isEnabled($conv->getProfileOwner(), 'filing')) ? $filer : ''),
'drop' => $drop, 'drop' => $drop,
'vote' => $buttons, 'vote' => $buttons,
'like' => $responses['like']['output'], 'like' => $responses['like']['output'],
@ -791,7 +792,7 @@ class Item extends BaseObject
'$edimg' => t('Image'), '$edimg' => t('Image'),
'$edurl' => t('Link'), '$edurl' => t('Link'),
'$edvideo' => t('Video'), '$edvideo' => t('Video'),
'$preview' => ((feature_enabled($conv->getProfileOwner(), 'preview')) ? t('Preview') : ''), '$preview' => ((Feature::isEnabled($conv->getProfileOwner(), 'preview')) ? t('Preview') : ''),
'$indent' => $indent, '$indent' => $indent,
'$sourceapp' => t($a->sourcename), '$sourceapp' => t($a->sourcename),
'$ww' => (($conv->getMode() === 'network') ? $ww : ''), '$ww' => (($conv->getMode() === 'network') ? $ww : ''),

72
src/Util/Pidfile.php Normal file
View file

@ -0,0 +1,72 @@
<?php
/**
* @file src/Util/Pidfile.php
*/
namespace Friendica\Util;
/**
* @brief Pidfile class
*/
class Pidfile
{
private $file;
private $running;
/**
* @param string $dir path
* @param string $name filename
* @return void
*/
public function __construct($dir, $name)
{
$this->_file = "$dir/$name.pid";
if (file_exists($this->_file)) {
$pid = trim(@file_get_contents($this->file));
if (($pid != "") && posix_kill($pid, 0)) {
$this->running = true;
}
}
if (! $this->running) {
$pid = getmypid();
file_put_contents($this->file, $pid);
}
}
/**
* @return void
*/
public function __destruct()
{
if ((! $this->running) && file_exists($this->file)) {
@unlink($this->file);
}
}
/**
* @return boolean
*/
public static function isRunning()
{
return self::$running;
}
/**
* @return object
*/
public static function runningTime()
{
return time() - @filectime(self::$file);
}
/**
* @return boolean
*/
public static function kill()
{
if (file_exists(self::$file)) {
return posix_kill(file_get_contents(self::$file), SIGTERM);
}
}
}

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* @file src/worker/CronJobs.php * @file src/worker/CronJobs.php
*/ */
@ -11,25 +12,27 @@ use Friendica\Core\Config;
use Friendica\Database\DBM; use Friendica\Database\DBM;
use Friendica\Model\GlobalContact; use Friendica\Model\GlobalContact;
use Friendica\Network\Probe; use Friendica\Network\Probe;
use Friendica\Object\Contact;
use Friendica\Protocol\PortableContact; use Friendica\Protocol\PortableContact;
use dba; use dba;
class CronJobs { class CronJobs
public static function execute($command = ''){ {
public static function execute($command = '')
{
global $a; global $a;
require_once 'include/datetime.php'; require_once 'include/datetime.php';
require_once 'include/post_update.php'; require_once 'include/post_update.php';
require_once 'mod/nodeinfo.php'; require_once 'mod/nodeinfo.php';
require_once 'include/photos.php'; require_once 'include/photos.php';
require_once 'include/user.php';
// No parameter set? So return // No parameter set? So return
if ($command == '') { if ($command == '') {
return; return;
} }
logger("Starting cronjob ".$command, LOGGER_DEBUG); logger("Starting cronjob " . $command, LOGGER_DEBUG);
// Call possible post update functions // Call possible post update functions
// see include/post_update.php for more details // see include/post_update.php for more details
@ -78,7 +81,7 @@ class CronJobs {
return; return;
} }
logger("Xronjob ".$command." is unknown.", LOGGER_DEBUG); logger("Xronjob " . $command . " is unknown.", LOGGER_DEBUG);
return; return;
} }
@ -86,7 +89,8 @@ class CronJobs {
/** /**
* @brief Update the cached values for the number of photo albums per user * @brief Update the cached values for the number of photo albums per user
*/ */
private static function updatePhotoAlbums() { private static function updatePhotoAlbums()
{
$r = q("SELECT `uid` FROM `user` WHERE NOT `account_expired` AND NOT `account_removed`"); $r = q("SELECT `uid` FROM `user` WHERE NOT `account_expired` AND NOT `account_removed`");
if (!DBM::is_result($r)) { if (!DBM::is_result($r)) {
return; return;
@ -100,7 +104,8 @@ class CronJobs {
/** /**
* @brief Expire and remove user entries * @brief Expire and remove user entries
*/ */
private static function expireAndRemoveUsers() { private static function expireAndRemoveUsers()
{
// expire any expired accounts // expire any expired accounts
q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0 q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0
AND `account_expires_on` > '%s' AND `account_expires_on` > '%s'
@ -120,9 +125,9 @@ class CronJobs {
* *
* @param App $a * @param App $a
*/ */
private static function clearCache(App $a) { private static function clearCache(App $a)
{
$last = Config::get('system','cache_last_cleared'); $last = Config::get('system', 'cache_last_cleared');
if ($last) { if ($last) {
$next = $last + (3600); // Once per hour $next = $last + (3600); // Once per hour
@ -142,16 +147,16 @@ class CronJobs {
clear_cache(); clear_cache();
// clear cache for photos // clear cache for photos
clear_cache($a->get_basepath(), $a->get_basepath()."/photo"); clear_cache($a->get_basepath(), $a->get_basepath() . "/photo");
// clear smarty cache // clear smarty cache
clear_cache($a->get_basepath()."/view/smarty3/compiled", $a->get_basepath()."/view/smarty3/compiled"); clear_cache($a->get_basepath() . "/view/smarty3/compiled", $a->get_basepath() . "/view/smarty3/compiled");
// clear cache for image proxy // clear cache for image proxy
if (!Config::get("system", "proxy_disabled")) { if (!Config::get("system", "proxy_disabled")) {
clear_cache($a->get_basepath(), $a->get_basepath()."/proxy"); clear_cache($a->get_basepath(), $a->get_basepath() . "/proxy");
$cachetime = Config::get('system','proxy_cache_time'); $cachetime = Config::get('system', 'proxy_cache_time');
if (!$cachetime) { if (!$cachetime) {
$cachetime = PROXY_DEFAULT_TIME; $cachetime = PROXY_DEFAULT_TIME;
} }
@ -166,13 +171,13 @@ class CronJobs {
dba::delete('parsed_url', array("`created` < NOW() - INTERVAL 3 MONTH")); dba::delete('parsed_url', array("`created` < NOW() - INTERVAL 3 MONTH"));
// Maximum table size in megabyte // Maximum table size in megabyte
$max_tablesize = intval(Config::get('system','optimize_max_tablesize')) * 1000000; $max_tablesize = intval(Config::get('system', 'optimize_max_tablesize')) * 1000000;
if ($max_tablesize == 0) { if ($max_tablesize == 0) {
$max_tablesize = 100 * 1000000; // Default are 100 MB $max_tablesize = 100 * 1000000; // Default are 100 MB
} }
if ($max_tablesize > 0) { if ($max_tablesize > 0) {
// Minimum fragmentation level in percent // Minimum fragmentation level in percent
$fragmentation_level = intval(Config::get('system','optimize_fragmentation')) / 100; $fragmentation_level = intval(Config::get('system', 'optimize_fragmentation')) / 100;
if ($fragmentation_level == 0) { if ($fragmentation_level == 0) {
$fragmentation_level = 0.3; // Default value is 30% $fragmentation_level = 0.3; // Default value is 30%
} }
@ -194,7 +199,7 @@ class CronJobs {
// Calculate fragmentation // Calculate fragmentation
$fragmentation = $table["Data_free"] / ($table["Data_length"] + $table["Index_length"]); $fragmentation = $table["Data_free"] / ($table["Data_length"] + $table["Index_length"]);
logger("Table ".$table["Name"]." - Fragmentation level: ".round($fragmentation * 100, 2), LOGGER_DEBUG); logger("Table " . $table["Name"] . " - Fragmentation level: " . round($fragmentation * 100, 2), LOGGER_DEBUG);
// Don't optimize tables that needn't to be optimized // Don't optimize tables that needn't to be optimized
if ($fragmentation < $fragmentation_level) { if ($fragmentation < $fragmentation_level) {
@ -202,12 +207,12 @@ class CronJobs {
} }
// So optimize it // So optimize it
logger("Optimize Table ".$table["Name"], LOGGER_DEBUG); logger("Optimize Table " . $table["Name"], LOGGER_DEBUG);
q("OPTIMIZE TABLE `%s`", dbesc($table["Name"])); q("OPTIMIZE TABLE `%s`", dbesc($table["Name"]));
} }
} }
Config::set('system','cache_last_cleared', time()); Config::set('system', 'cache_last_cleared', time());
} }
/** /**
@ -215,8 +220,8 @@ class CronJobs {
* *
* @param App $a * @param App $a
*/ */
private static function repairDiaspora(App $a) { private static function repairDiaspora(App $a)
{
$starttime = time(); $starttime = time();
$r = q("SELECT `id`, `url` FROM `contact` $r = q("SELECT `id`, `url` FROM `contact`
@ -241,7 +246,7 @@ class CronJobs {
continue; continue;
} }
logger("Repair contact ".$contact["id"]." ".$contact["url"], LOGGER_DEBUG); logger("Repair contact " . $contact["id"] . " " . $contact["url"], LOGGER_DEBUG);
q("UPDATE `contact` SET `batch` = '%s', `notify` = '%s', `poll` = '%s', pubkey = '%s' WHERE `id` = %d", q("UPDATE `contact` SET `batch` = '%s', `notify` = '%s', `poll` = '%s', pubkey = '%s' WHERE `id` = %d",
dbesc($data["batch"]), dbesc($data["notify"]), dbesc($data["poll"]), dbesc($data["pubkey"]), dbesc($data["batch"]), dbesc($data["notify"]), dbesc($data["poll"]), dbesc($data["pubkey"]),
intval($contact["id"])); intval($contact["id"]));
@ -252,15 +257,15 @@ class CronJobs {
* @brief Do some repairs in database entries * @brief Do some repairs in database entries
* *
*/ */
private static function repairDatabase() { private static function repairDatabase()
{
// Sometimes there seem to be issues where the "self" contact vanishes. // Sometimes there seem to be issues where the "self" contact vanishes.
// We haven't found the origin of the problem by now. // We haven't found the origin of the problem by now.
$r = q("SELECT `uid` FROM `user` WHERE NOT EXISTS (SELECT `uid` FROM `contact` WHERE `contact`.`uid` = `user`.`uid` AND `contact`.`self`)"); $r = q("SELECT `uid` FROM `user` WHERE NOT EXISTS (SELECT `uid` FROM `contact` WHERE `contact`.`uid` = `user`.`uid` AND `contact`.`self`)");
if (DBM::is_result($r)) { if (DBM::is_result($r)) {
foreach ($r AS $user) { foreach ($r AS $user) {
logger('Create missing self contact for user '.$user['uid']); logger('Create missing self contact for user ' . $user['uid']);
user_create_self_contact($user['uid']); Contact::createSelfFromUserId($user['uid']);
} }
} }