[Plugins] Incorporated GNUsocialExtendedProfile as part of ExtendedProfile

Also improved a lot of the plugin and made things in a way it would make sense
This commit is contained in:
Diogo Cordeiro 2019-08-09 15:22:55 +01:00
parent 90bd9088bb
commit 88bdb5114f
153 changed files with 2187 additions and 3530 deletions

View File

@ -61,8 +61,8 @@ class Widget
* Prepare the widget for use
*
* @param Action $out output helper, defaults to null
* @param array $widgetOpts
*/
function __construct(Action $out = null, array $widgetOpts = [])
{
$this->out = $out;

View File

@ -1,46 +1,50 @@
<?php
/*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2011, StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('STATUSNET')) {
exit(1);
}
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Extra profile bio-like fields
* Extra profile bio-like fields and allows administrators to define
* additional profile fields for the users of a GNU social installation.
*
* @package ExtendedProfilePlugin
* @maintainer Brion Vibber <brion@status.net>
* @category Widget
* @package GNU social
* @author Brion Vibber <brion@status.net>
* @author Max Shinn <trombonechamp@gmail.com>
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @copyright 2011-2019 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
defined('GNUSOCIAL') || die();
include_once __DIR__ . '/lib/profiletools.php';
class ExtendedProfilePlugin extends Plugin
{
const PLUGIN_VERSION = '2.0.0';
const PLUGIN_VERSION = '3.0.0';
public function onPluginVersion(array &$versions): bool
{
$versions[] = array(
$versions[] = [
'name' => 'ExtendedProfile',
'version' => self::PLUGIN_VERSION,
'author' => 'Brion Vibber, Samantha Doherty, Zach Copley',
'author' => 'Brion Vibber, Samantha Doherty, Zach Copley, Max Shinn, Diogo Cordeiro',
'homepage' => 'https://git.gnu.io/gnu/gnu-social/tree/master/plugins/ExtendedProfile',
// TRANS: Plugin description.
// TRANS: Module description.
'rawdescription' => _m('UI extensions for additional profile fields.')
);
];
return true;
}
@ -52,41 +56,160 @@ class ExtendedProfilePlugin extends Plugin
*
* @param URLMapper $m URL mapper
*
* @return boolean hook return
* @return bool hook return
* @throws Exception
*/
public function onStartInitializeRouter(URLMapper $m)
{
$m->connect(
':nickname/detail',
array('action' => 'profiledetail'),
array('nickname' => Nickname::DISPLAY_FMT)
['action' => 'profiledetail'],
['nickname' => Nickname::DISPLAY_FMT]
);
$m->connect(
'/settings/profile/finduser',
array('action' => 'Userautocomplete')
['action' => 'Userautocomplete']
);
$m->connect(
'settings/profile/detail',
array('action' => 'profiledetailsettings')
['action' => 'profiledetailsettings']
);
$m->connect(
'admin/profilefields',
['action' => 'profilefieldsAdminPanel']
);
return true;
}
function onCheckSchema()
public function onCheckSchema()
{
$schema = Schema::get();
$schema->ensureTable('profile_detail', Profile_detail::schemaDef());
$schema->ensureTable('gnusocialprofileextensionfield', GNUsocialProfileExtensionField::schemaDef());
$schema->ensureTable('gnusocialprofileextensionresponse', GNUsocialProfileExtensionResponse::schemaDef());
return true;
}
public function onEndShowAccountProfileBlock(HTMLOutputter $out, Profile $profile)
{
$user = User::getKV('id', $profile->id);
if ($user) {
$url = common_local_url('profiledetail', ['nickname' => $user->nickname]);
// TRANS: Link text on user profile page leading to extended profile page.
$out->element('a', ['href' => $url, 'class' => 'profiledetail'], _m('More details...'));
}
}
/**
* Menu item for personal subscriptions/groups area
*
* @param Action $action action being executed
*
* @return bool hook return
* @throws Exception
*/
public function onEndAccountSettingsNav(Action $action)
{
$action_name = $action->trimmed('action');
$action->menuItem(
common_local_url('profiledetailsettings'),
// TRANS: Extended profile plugin menu item on user settings page.
_m('MENU', 'Full Profile'),
// TRANS: Extended profile plugin tooltip for user settings menu item.
_m('Change your extended profile settings'),
$action_name === 'profiledetailsettings'
);
return true;
}
function onEndShowAccountProfileBlock(HTMLOutputter $out, Profile $profile) {
$user = User::getKV('id', $profile->id);
if ($user) {
$url = common_local_url('profiledetail', array('nickname' => $user->nickname));
// TRANS: Link text on user profile page leading to extended profile page.
$out->element('a', array('href' => $url, 'class' => 'profiledetail'), _m('More details...'));
/*public function onEndProfileFormData(Action $action): bool
{
$fields = GNUsocialProfileExtensionField::allFields();
$user = common_current_user();
$profile = $user->getProfile();
gnusocial_profile_merge($profile);
foreach ($fields as $field) {
$action->elementStart('li');
$fieldname = $field->systemname;
if ($field->type == 'str') {
$action->input(
$fieldname,
$field->title,
($action->arg($fieldname)) ? $action->arg($fieldname) : $profile->$fieldname,
$field->description
);
} elseif ($field->type == 'text') {
$action->textarea(
$fieldname,
$field->title,
($action->arg($fieldname)) ? $action->arg($fieldname) : $profile->$fieldname,
$field->description
);
}
$action->elementEnd('li');
}
return true;
}
public function onEndProfileSaveForm(Action $action): bool
{
$fields = GNUsocialProfileExtensionField::allFields();
$user = common_current_user();
$profile = $user->getProfile();
foreach ($fields as $field) {
$val = $action->trimmed($field->systemname);
$response = new GNUsocialProfileExtensionResponse();
$response->profile_id = $profile->id;
$response->extension_id = $field->id;
if ($response->find()) {
$response->fetch();
$response->value = $val;
if ($response->validate()) {
if (empty($val)) {
$response->delete();
} else {
$response->update();
}
}
} else {
$response->value = $val;
$response->insert();
}
}
return true;
}*/
public function onEndShowStyles(Action $action): bool
{
$action->cssLink('/plugins/ExtendedProfile/css/profiledetail.css');
return true;
}
public function onEndShowScripts(Action $action): bool
{
$action->script('plugins/ExtendedProfile/js/profiledetail.js');
return true;
}
public function onEndAdminPanelNav(AdminPanelNav $nav): bool
{
if (AdminPanelAction::canAdmin('profilefields')) {
$action_name = $nav->action->trimmed('action');
$nav->out->menuItem(
'/admin/profilefields',
_m('Profile Fields'),
_m('Custom profile fields'),
$action_name == 'profilefieldsadminpanel',
'nav_profilefields_admin_panel'
);
}
return true;
}
}

View File

@ -6,9 +6,16 @@ The ExtendedProfile plugin adds additional profile fields such as:
* Work experience
* Education
And allows administrators to define additional profile fields for the
users of a GNU social installation.
Installation
============
add "addPlugin('ExtendedProfile');"
add
addPlugin('ExtendedProfile');
$config['admin']['panels'][] = 'profilefields';
to the bottom of your config.php
Note: This plugin is enabled by default on private instances.
@ -17,7 +24,3 @@ Settings
========
none
Example
=======
addPlugin('ExtendedProfile');

View File

@ -17,38 +17,44 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('GNUSOCIAL')) { exit(1); }
if (!defined('GNUSOCIAL')) {
exit(1);
}
class ProfileDetailAction extends ShowstreamAction
{
function isReadOnly($args)
public function isReadOnly($args)
{
return true;
}
function title()
public function title()
{
return $this->target->getFancyName();
}
function showStylesheets() {
public function showStylesheets()
{
parent::showStylesheets();
$this->cssLink('plugins/ExtendedProfile/css/profiledetail.css');
return true;
}
function showContent()
public function showContent()
{
$cur = common_current_user();
if ($this->scoped instanceof Profile && $this->scoped->sameAs($this->target)) {
$this->elementStart('div', 'entity_actions');
$this->elementStart('ul');
$this->elementStart('li', 'entity_edit');
$this->element('a', array('href' => common_local_url('profiledetailsettings'),
// TRANS: Link title for link on user profile.
'title' => _m('Edit extended profile settings')),
// TRANS: Link text for link on user profile.
_m('Edit'));
$this->element(
'a',
array('href' => common_local_url('profiledetailsettings'),
// TRANS: Link title for link on user profile.
'title' => _m('Edit extended profile settings')),
// TRANS: Link text for link on user profile.
_m('Edit')
);
$this->elementEnd('li');
$this->elementEnd('ul');
$this->elementEnd('div');

View File

@ -17,23 +17,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('GNUSOCIAL')) { exit(1); }
if (!defined('GNUSOCIAL')) {
exit(1);
}
class ProfileDetailSettingsAction extends ProfileSettingsAction
{
function title()
public function title()
{
// TRANS: Title for extended profile settings.
return _m('Extended profile settings');
}
function showStylesheets() {
public function showStylesheets()
{
parent::showStylesheets();
$this->cssLink('plugins/ExtendedProfile/css/profiledetail.css');
return true;
}
function showScripts() {
public function showScripts()
{
parent::showScripts();
$this->script('plugins/ExtendedProfile/js/profiledetail.js');
return true;
@ -49,7 +53,7 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
throw new ClientException(_m('Unexpected form submission.'));
}
function showContent()
public function showContent()
{
$widget = new ExtendedProfileWidget(
$this,
@ -59,14 +63,14 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
$widget->show();
}
function saveDetails()
public function saveDetails()
{
common_debug(var_export($_POST, true));
$this->saveStandardProfileDetails();
$simpleFieldNames = array('title', 'spouse', 'kids', 'manager');
$dateFieldNames = array('birthday');
$dateFieldNames = array('birthday');
foreach ($simpleFieldNames as $name) {
$value = $this->trimmed('extprofile-' . $name);
@ -92,19 +96,19 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
$this->saveWebsites();
$this->saveExperiences();
$this->saveEducations();
$this->saveCustomFields($this);
// TRANS: Success message after saving extended profile details.
return _m('Details saved.');
}
function parseDate($fieldname, $datestr, $required = false)
public function parseDate($fieldname, $datestr, $required = false)
{
if (empty($datestr)) {
if ($required) {
$msg = sprintf(
// TRANS: Exception thrown when no date was entered in a required date field.
// TRANS: %s is the field name.
// TRANS: Exception thrown when no date was entered in a required date field.
// TRANS: %s is the field name.
_m('You must supply a date for "%s".'),
$fieldname
);
@ -115,8 +119,8 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
if ($ts === false) {
throw new Exception(
sprintf(
// TRANS: Exception thrown on incorrect data input.
// TRANS: %1$s is a field name, %2$s is the incorrect input.
// TRANS: Exception thrown on incorrect data input.
// TRANS: %1$s is a field name, %2$s is the incorrect input.
_m('Invalid date entered for "%1$s": %2$s.'),
$fieldname,
$ts
@ -128,11 +132,12 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
return null;
}
function savePhoneNumbers() {
public function savePhoneNumbers()
{
$phones = $this->findPhoneNumbers();
$this->removeAll('phone');
$i = 0;
foreach($phones as $phone) {
foreach ($phones as $phone) {
if (!empty($phone['value'])) {
++$i;
$this->saveField(
@ -145,51 +150,54 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
}
}
function findPhoneNumbers() {
public function findPhoneNumbers()
{
// Form vals look like this:
// 'extprofile-phone-1' => '11332',
// 'extprofile-phone-1-rel' => 'mobile',
$phones = $this->sliceParams('phone', 2);
$phones = $this->sliceParams('phone', 2);
$phoneArray = array();
foreach ($phones as $phone) {
list($number, $rel) = array_values($phone);
$phoneArray[] = array(
'value' => $number,
'rel' => $rel
'rel' => $rel
);
}
return $phoneArray;
}
function findIms() {
public function findIms()
{
// Form vals look like this:
// 'extprofile-im-0' => 'jed',
// 'extprofile-im-0-rel' => 'yahoo',
$ims = $this->sliceParams('im', 2);
$ims = $this->sliceParams('im', 2);
$imArray = array();
foreach ($ims as $im) {
list($id, $rel) = array_values($im);
$imArray[] = array(
'value' => $id,
'rel' => $rel
'rel' => $rel
);
}
return $imArray;
}
function saveIms() {
public function saveIms()
{
$ims = $this->findIms();
$this->removeAll('im');
$i = 0;
foreach($ims as $im) {
foreach ($ims as $im) {
if (!empty($im['value'])) {
++$i;
$this->saveField(
@ -202,7 +210,8 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
}
}
function findWebsites() {
public function findWebsites()
{
// Form vals look like this:
@ -213,18 +222,19 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
list($id, $rel) = array_values($site);
$wsArray[] = array(
'value' => $id,
'rel' => $rel
'rel' => $rel
);
}
return $wsArray;
}
function saveWebsites() {
public function saveWebsites()
{
$sites = $this->findWebsites();
$this->removeAll('website');
$i = 0;
foreach($sites as $site) {
foreach ($sites as $site) {
if (!empty($site['value']) && !common_valid_http_url($site['value'])) {
// TRANS: Exception thrown when entering an invalid URL.
// TRANS: %s is the invalid URL.
@ -243,7 +253,8 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
}
}
function findExperiences() {
public function findExperiences()
{
// Form vals look like this:
// 'extprofile-experience-0' => 'Bozotronix',
@ -264,8 +275,8 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
if (!empty($company)) {
$expArray[] = array(
'company' => $company,
'start' => $this->parseDate('Start', $start, true),
'end' => ($current == 'false') ? $this->parseDate('End', $end, true) : null,
'start' => $this->parseDate('Start', $start, true),
'end' => ($current == 'false') ? $this->parseDate('End', $end, true) : null,
'current' => ($current == 'false') ? false : true
);
}
@ -274,7 +285,8 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
return $expArray;
}
function saveExperiences() {
public function saveExperiences()
{
common_debug('save experiences');
$experiences = $this->findExperiences();
@ -283,7 +295,7 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
$this->removeAll('end'); // also stores 'current'
$i = 0;
foreach($experiences as $experience) {
foreach ($experiences as $experience) {
if (!empty($experience['company'])) {
++$i;
$this->saveField(
@ -318,12 +330,12 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
$experience['end']
);
}
}
}
}
function findEducations() {
public function findEducations()
{
// Form vals look like this:
// 'extprofile-education-0-school' => 'Pigdog',
@ -339,11 +351,11 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
list($school, $degree, $description, $end, $start) = array_values($edu);
if (!empty($school)) {
$eduArray[] = array(
'school' => $school,
'degree' => $degree,
'school' => $school,
'degree' => $degree,
'description' => $description,
'start' => $this->parseDate('Start', $start, true),
'end' => $this->parseDate('End', $end, true)
'start' => $this->parseDate('Start', $start, true),
'end' => $this->parseDate('End', $end, true)
);
}
}
@ -352,59 +364,60 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
}
function saveEducations() {
common_debug('save education');
$edus = $this->findEducations();
common_debug(var_export($edus, true));
public function saveEducations()
{
common_debug('save education');
$edus = $this->findEducations();
common_debug(var_export($edus, true));
$this->removeAll('school');
$this->removeAll('degree');
$this->removeAll('degree_descr');
$this->removeAll('school_start');
$this->removeAll('school_end');
$this->removeAll('school');
$this->removeAll('degree');
$this->removeAll('degree_descr');
$this->removeAll('school_start');
$this->removeAll('school_end');
$i = 0;
foreach($edus as $edu) {
if (!empty($edu['school'])) {
++$i;
$this->saveField(
'school',
$edu['school'],
null,
$i
);
$this->saveField(
'degree',
$edu['degree'],
null,
$i
);
$this->saveField(
'degree_descr',
$edu['description'],
null,
$i
);
$this->saveField(
'school_start',
null,
null,
$i,
$edu['start']
);
$i = 0;
foreach ($edus as $edu) {
if (!empty($edu['school'])) {
++$i;
$this->saveField(
'school',
$edu['school'],
null,
$i
);
$this->saveField(
'degree',
$edu['degree'],
null,
$i
);
$this->saveField(
'degree_descr',
$edu['description'],
null,
$i
);
$this->saveField(
'school_start',
null,
null,
$i,
$edu['start']
);
$this->saveField(
'school_end',
null,
null,
$i,
$edu['end']
);
$this->saveField(
'school_end',
null,
null,
$i,
$edu['end']
);
}
}
}
}
}
function arraySplit($array, $pieces)
public function arraySplit($array, $pieces)
{
if ($pieces < 2) {
return array($array);
@ -417,9 +430,10 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
return array_merge(array($a), $b);
}
function findMultiParams($type) {
public function findMultiParams($type)
{
$formVals = array();
$target = $type;
$target = $type;
foreach ($_POST as $key => $val) {
if (strrpos('extprofile-' . $key, $target) !== false) {
$formVals[$key] = $val;
@ -428,7 +442,8 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
return $formVals;
}
function sliceParams($key, $size) {
public function sliceParams($key, $size)
{
$slice = array();
$params = $this->findMultiParams($key);
ksort($params);
@ -439,28 +454,29 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
/**
* Save an extended profile field as a Profile_detail
*
* @param string $name field name
* @param string $value field value
* @param string $rel field rel (type)
* @param int $index index (fields can have multiple values)
* @param date $date related date
* @param string $name field name
* @param string $value field value
* @param string|null $rel field rel (type)
* @param int|null $index index (fields can have multiple values)
* @param string|null $date date related date
* @throws ServerException
*/
function saveField($name, $value, $rel = null, $index = null, $date = null)
public function saveField(string $name, ?string $value, ?string $rel = null, ?int $index = null, ?string $date = null)
{
$detail = new Profile_detail();
$detail = new Profile_detail();
$detail->profile_id = $this->scoped->getID();
$detail->field_name = $name;
$detail->profile_id = $this->scoped->getID();
$detail->field_name = $name;
$detail->value_index = $index;
$result = $detail->find(true);
if (!$result instanceof Profile_detail) {
$detail->value_index = $index;
$detail->rel = $rel;
$detail->rel = $rel;
$detail->field_value = $value;
$detail->date = $date;
$detail->created = common_sql_now();
$detail->date = $date;
$detail->created = common_sql_now();
$result = $detail->insert();
if ($result === false) {
common_log_db_error($detail, 'INSERT', __FILE__);
@ -471,8 +487,8 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
$orig = clone($detail);
$detail->field_value = $value;
$detail->rel = $rel;
$detail->date = $date;
$detail->rel = $rel;
$detail->date = $date;
$result = $detail->update($orig);
if ($result === false) {
@ -485,11 +501,11 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
$detail->free();
}
function removeAll($name)
public function removeAll($name)
{
$detail = new Profile_detail();
$detail->profile_id = $this->scoped->getID();
$detail->field_name = $name;
$detail = new Profile_detail();
$detail->profile_id = $this->scoped->getID();
$detail->field_name = $name;
$detail->delete();
$detail->free();
}
@ -500,12 +516,12 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
* XXX: There's a lot of dupe code here from ProfileSettingsAction.
* Do not want.
*/
function saveStandardProfileDetails()
public function saveStandardProfileDetails()
{
$fullname = $this->trimmed('extprofile-fullname');
$location = $this->trimmed('extprofile-location');
$fullname = $this->trimmed('extprofile-fullname');
$location = $this->trimmed('extprofile-location');
$tagstring = $this->trimmed('extprofile-tags');
$bio = $this->trimmed('extprofile-bio');
$bio = $this->trimmed('extprofile-bio');
if ($tagstring) {
$tags = array_map(
@ -513,7 +529,7 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
preg_split('/[\s,]+/', $tagstring)
);
} else {
$tags = array();
$tags = [];
}
foreach ($tags as $tag) {
@ -527,30 +543,29 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
$oldTags = Profile_tag::getSelfTagsArray($this->scoped);
$newTags = array_diff($tags, $oldTags);
if ($fullname != $this->scoped->getFullname()
if ($fullname != $this->scoped->getFullname()
|| $location != $this->scoped->location
|| !empty($newTags)
|| $bio != $this->scoped->getDescription()) {
|| $bio != $this->scoped->getDescription()) {
$orig = clone($this->scoped);
// Skipping nickname change here until we add logic for when the site allows it or not
// old Profilesettings will still let us do that.
$this->scoped->fullname = $fullname;
$this->scoped->bio = $bio;
$this->scoped->bio = $bio;
$this->scoped->location = $location;
$loc = Location::fromName($location);
if (empty($loc)) {
$this->scoped->lat = null;
$this->scoped->lon = null;
$this->scoped->lat = null;
$this->scoped->lon = null;
$this->scoped->location_id = null;
$this->scoped->location_ns = null;
} else {
$this->scoped->lat = $loc->lat;
$this->scoped->lon = $loc->lon;
$this->scoped->lat = $loc->lat;
$this->scoped->lon = $loc->lon;
$this->scoped->location_id = $loc->location_id;
$this->scoped->location_ns = $loc->location_ns;
}
@ -570,4 +585,36 @@ class ProfileDetailSettingsAction extends ProfileSettingsAction
}
}
private function saveCustomFields($action)
{
$fields = GNUsocialProfileExtensionField::allFields();
$user = common_current_user();
$profile = $user->getProfile();
foreach ($fields as $field) {
$val = $action->trimmed('extprofile-'.$field->systemname);
if (empty($val)) {
continue;
}
$response = new GNUsocialProfileExtensionResponse();
$response->profile_id = $profile->id;
$response->extension_id = $field->id;
if ($response->find()) {
$response->fetch();
$response->value = $val;
if ($response->validate()) {
if (empty($val)) {
$response->delete();
} else {
$response->update();
}
}
} else {
$response->value = $val;
$response->insert();
}
}
}
}

View File

@ -144,7 +144,7 @@ class ProfilefieldsAdminForm extends AdminForm
'systemname',
_m('Internal name'),
$systemname,
_m('The alphanumeric name used internally for this field. Also the key used in OStatus user info. (optional)')
_m('The alphanumeric name used internally for this field. Also the key used for federation (e.g. ActivityPub and OStatus) user info.')
);
$this->unli();
$this->li();

View File

@ -34,7 +34,7 @@ if (!defined('STATUSNET')) {
class UserautocompleteAction extends Action
{
var $query;
public $query;
/**
* Initialization.
@ -42,8 +42,9 @@ class UserautocompleteAction extends Action
* @param array $args Web and URL arguments
*
* @return boolean true if nothing goes wrong
* @throws ClientException
*/
function prepare(array $args = array())
public function prepare(array $args = array())
{
parent::prepare($args);
$this->query = $this->trimmed('term');
@ -53,11 +54,9 @@ class UserautocompleteAction extends Action
/**
* Handle a request
*
* @param array $args Arguments from $_REQUEST
*
* @return void
*/
function handle()
public function handle()
{
parent::handle();
$this->showResults();
@ -68,8 +67,9 @@ class UserautocompleteAction extends Action
* as a quick-n-dirty JSON document
*
* @return void
* @throws ServerException
*/
function showResults()
public function showResults()
{
$people = array();
@ -83,7 +83,6 @@ class UserautocompleteAction extends Action
$cnt = $profile->find();
if ($cnt > 0) {
$sql = 'SELECT profile.* FROM profile, user WHERE profile.id = user.id '
. ' AND LEFT(LOWER(profile.nickname), '
. strlen($this->query)
@ -92,9 +91,9 @@ class UserautocompleteAction extends Action
$profile->query(sprintf($sql, $this->query));
}
while ($profile->fetch()) {
$people[] = $profile->nickname;
$people[] = $profile->nickname;
}
header('Content-Type: application/json; charset=utf-8');
@ -104,9 +103,10 @@ class UserautocompleteAction extends Action
/**
* Do we need to write to the database?
*
* @param $args
* @return boolean true
*/
function isReadOnly($args)
public function isReadOnly($args)
{
return true;
}

View File

@ -69,30 +69,30 @@ class Profile_detail extends Managed_DataObject
public $created;
public $modified;
static function schemaDef()
public static function schemaDef()
{
return array(
// No need for i18n. Table properties.
'description'
=> 'Additional profile details for the ExtendedProfile plugin',
'fields' => array(
'id' => array('type' => 'serial', 'not null' => true),
'profile_id' => array('type' => 'int', 'not null' => true),
'field_name' => array(
'type' => 'varchar',
'length' => 16,
=> 'Additional profile details for the ExtendedProfile plugin',
'fields' => array(
'id' => array('type' => 'serial', 'not null' => true),
'profile_id' => array('type' => 'int', 'not null' => true),
'field_name' => array(
'type' => 'varchar',
'length' => 16,
'not null' => true
),
'value_index' => array('type' => 'int'),
'field_value' => array('type' => 'text'),
'date' => array('type' => 'datetime'),
'rel' => array('type' => 'varchar', 'length' => 16),
'date' => array('type' => 'datetime'),
'rel' => array('type' => 'varchar', 'length' => 16),
'rel_profile' => array('type' => 'int'),
'created' => array(
'type' => 'datetime',
'created' => array(
'type' => 'datetime',
'not null' => true
),
'modified' => array(
),
'modified' => array(
'type' => 'timestamp',
'not null' => true
),
@ -100,7 +100,7 @@ class Profile_detail extends Managed_DataObject
'primary key' => array('id'),
'unique keys' => array(
'profile_detail_profile_id_field_name_value_index'
=> array('profile_id', 'field_name', 'value_index'),
=> array('profile_id', 'field_name', 'value_index'),
)
);
}

View File

@ -32,12 +32,13 @@ class ExtendedProfile
* Constructor
*
* @param Profile $profile
* @throws NoSuchUserException
*/
function __construct(Profile $profile)
public function __construct(Profile $profile)
{
$this->profile = $profile;
$this->user = $profile->getUser();
$this->fields = $this->loadFields();
$this->profile = $profile;
$this->user = $profile->getUser();
$this->fields = $this->loadFields();
$this->sections = $this->getSections();
//common_debug(var_export($this->sections, true));
@ -48,8 +49,9 @@ class ExtendedProfile
* Load extended profile fields
*
* @return array $fields the list of fields
* @throws Exception
*/
function loadFields()
public function loadFields()
{
$detail = new Profile_detail();
$detail->profile_id = $this->profile->getID();
@ -69,7 +71,7 @@ class ExtendedProfile
*
* @return string the concatenated string of tags
*/
function getTags()
public function getTags()
{
return implode(' ', Profile_tag::getSelfTagsArray($this->profile));
}
@ -84,21 +86,22 @@ class ExtendedProfile
*
* @return string the value
*/
function getTextValue($name)
public function getTextValue($name)
{
$key = strtolower($name);
$key = strtolower($name);
$profileFields = array('fullname', 'location', 'bio');
if (in_array($key, $profileFields)) {
return $this->profile->$name;
} else if (array_key_exists($key, $this->fields)) {
} elseif (array_key_exists($key, $this->fields)) {
return $this->fields[$key][0]->field_value;
} else {
return null;
}
}
function getDateValue($name) {
public function getDateValue($name)
{
$key = strtolower($name);
if (array_key_exists($key, $this->fields)) {
return $this->fields[$key][0]->date;
@ -109,7 +112,7 @@ class ExtendedProfile
// XXX: getPhones, getIms, and getWebsites pretty much do the same thing,
// so refactor.
function getPhones()
public function getPhones()
{
$phones = (isset($this->fields['phone'])) ? $this->fields['phone'] : null;
$pArrays = array();
@ -119,9 +122,9 @@ class ExtendedProfile
// TRANS: Field label for extended profile properties.
'label' => _m('Phone'),
'index' => 0,
'type' => 'phone',
'type' => 'phone',
'vcard' => 'tel',
'rel' => 'office',
'rel' => 'office',
'value' => null
);
} else {
@ -129,20 +132,20 @@ class ExtendedProfile
$pa = array(
// TRANS: Field label for extended profile properties.
'label' => _m('Phone'),
'type' => 'phone',
'type' => 'phone',
'index' => intval($phones[$i]->value_index),
'rel' => $phones[$i]->rel,
'rel' => $phones[$i]->rel,
'value' => $phones[$i]->field_value,
'vcard' => 'tel'
);
$pArrays[] = $pa;
$pArrays[] = $pa;
}
}
return $pArrays;
}
function getIms()
public function getIms()
{
$ims = (isset($this->fields['im'])) ? $this->fields['im'] : null;
$iArrays = array();
@ -158,9 +161,9 @@ class ExtendedProfile
$ia = array(
// TRANS: Field label for extended profile properties (Instant Messaging).
'label' => _m('IM'),
'type' => 'im',
'type' => 'im',
'index' => intval($ims[$i]->value_index),
'rel' => $ims[$i]->rel,
'rel' => $ims[$i]->rel,
'value' => $ims[$i]->field_value,
);
@ -170,7 +173,7 @@ class ExtendedProfile
return $iArrays;
}
function getWebsites()
public function getWebsites()
{
$sites = (isset($this->fields['website'])) ? $this->fields['website'] : null;
$wArrays = array();
@ -186,9 +189,9 @@ class ExtendedProfile
$wa = array(
// TRANS: Field label for extended profile properties.
'label' => _m('Website'),
'type' => 'website',
'type' => 'website',
'index' => intval($sites[$i]->value_index),
'rel' => $sites[$i]->rel,
'rel' => $sites[$i]->rel,
'value' => $sites[$i]->field_value,
);
@ -198,44 +201,44 @@ class ExtendedProfile
return $wArrays;
}
function getExperiences()
public function getExperiences()
{
$companies = (isset($this->fields['company'])) ? $this->fields['company'] : null;
$start = (isset($this->fields['start'])) ? $this->fields['start'] : null;
$end = (isset($this->fields['end'])) ? $this->fields['end'] : null;
$end = (isset($this->fields['end'])) ? $this->fields['end'] : null;
$eArrays = array();
if (empty($companies)) {
$eArrays[] = array(
// TRANS: Field label for extended profile properties.
'label' => _m('Employer'),
'type' => 'experience',
'label' => _m('Employer'),
'type' => 'experience',
'company' => null,
'start' => null,
'end' => null,
'start' => null,
'end' => null,
'current' => false,
'index' => 0
'index' => 0
);
} else {
for ($i = 0; $i < sizeof($companies); $i++) {
$ea = array(
// TRANS: Field label for extended profile properties.
'label' => _m('Employer'),
'type' => 'experience',
'label' => _m('Employer'),
'type' => 'experience',
'company' => $companies[$i]->field_value,
'index' => intval($companies[$i]->value_index),
'index' => intval($companies[$i]->value_index),
'current' => $end[$i]->rel,
'start' => $start[$i]->date,
'end' => $end[$i]->date
'start' => $start[$i]->date,
'end' => $end[$i]->date
);
$eArrays[] = $ea;
$eArrays[] = $ea;
}
}
return $eArrays;
}
function getEducation()
public function getEducation()
{
$schools = (isset($this->fields['school'])) ? $this->fields['school'] : null;
$degrees = (isset($this->fields['degree'])) ? $this->fields['degree'] : null;
@ -259,17 +262,17 @@ class ExtendedProfile
} else {
for ($i = 0; $i < sizeof($schools); $i++) {
$ia = array(
'type' => 'education',
'type' => 'education',
// TRANS: Field label for extended profile properties.
'label' => _m('Institution'),
'school' => $schools[$i]->field_value,
'degree' => isset($degrees[$i]->field_value) ? $degrees[$i]->field_value : null,
'label' => _m('Institution'),
'school' => $schools[$i]->field_value,
'degree' => isset($degrees[$i]->field_value) ? $degrees[$i]->field_value : null,
'description' => isset($descs[$i]->field_value) ? $descs[$i]->field_value : null,
'index' => intval($schools[$i]->value_index),
'start' => $start[$i]->date,
'end' => $end[$i]->date
'index' => intval($schools[$i]->value_index),
'start' => $start[$i]->date,
'end' => $end[$i]->date
);
$iArrays[] = $ia;
$iArrays[] = $ia;
}
}
@ -280,9 +283,27 @@ class ExtendedProfile
* Return all the sections of the extended profile
*
* @return array the big list of sections and fields
* @throws Exception
*/
function getSections()
public function getSections()
{
$gsefields = GNUsocialProfileExtensionField::allFields();
$extra_fields = [];
gnusocial_profile_merge($this->profile);
foreach ($gsefields as $field) {
$field_key = $field->systemname;
switch ($field->type) {
case 'text':
$extra_fields[$field_key]['type'] = 'custom-textarea';
break;
case 'str':
default:
$extra_fields[$field_key]['type'] = 'custom-text';
break;
}
$extra_fields[$field_key]['label'] = $field->title;
$extra_fields[$field_key]['value'] = $this->profile->$field_key;
}
return array(
'basic' => array(
// TRANS: Field label for extended profile properties.
@ -328,8 +349,8 @@ class ExtendedProfile
// TRANS: Field label for extended profile properties.
'label' => _m('Contact'),
'fields' => array(
'phone' => $this->getPhones(),
'im' => $this->getIms(),
'phone' => $this->getPhones(),
'im' => $this->getIms(),
'website' => $this->getWebsites()
),
),
@ -368,6 +389,10 @@ class ExtendedProfile
'education' => $this->getEducation()
),
),
'extra' => [
'label' => _m('Extra fields'),
'fields' => $extra_fields,