123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704 |
- <?php
- // 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/>.
- /*
- * Class for outputting a widget to display or edit
- * extended profiles
- *
- * @copyright 2011 StatusNet, Inc.
- * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
- */
- defined('GNUSOCIAL') || die();
- class ExtendedProfileWidget extends Form
- {
- const EDITABLE = true;
- /**
- * The parent profile
- *
- * @var Profile
- */
- protected $profile;
- /**
- * The extended profile
- *
- * @var ExtendedProfile
- */
- protected $ext;
- /**
- * Constructor
- *
- * @param Action $out
- * @param Profile $profile
- * @param boolean $editable
- * @throws NoSuchUserException
- */
- public function __construct(Action $out = null, Profile $profile = null, $editable = false)
- {
- parent::__construct($out);
- $this->profile = $profile;
- $this->ext = new ExtendedProfile($this->profile);
- $this->editable = $editable;
- }
- /**
- * Show the extended profile, or the edit form
- */
- public function show()
- {
- if ($this->editable) {
- parent::show();
- } else {
- $this->showSections();
- }
- }
- /**
- * Show form data
- */
- public function formData()
- {
- // For JQuery UI modal dialog
- $this->out->elementStart(
- 'div',
- // TRANS: Title for extended profile entry deletion dialog.
- array('id' => 'confirm-dialog', 'title' => _m('Confirmation Required'))
- );
- // TRANS: Confirmation text for extended profile entry deletion dialog.
- $this->out->text(_m('Really delete this entry?'));
- $this->out->elementEnd('div');
- $this->showSections();
- }
- /**
- * Show each section of the extended profile
- */
- public function showSections()
- {
- $sections = $this->ext->getSections();
- foreach ($sections as $name => $section) {
- $this->showExtendedProfileSection($name, $section);
- }
- }
- /**
- * Show an extended profile section
- *
- * @param string $name name of the section
- * @param array $section array of fields for the section
- * @throws Exception
- */
- protected function showExtendedProfileSection($name, $section)
- {
- $this->out->element('h3', null, $section['label']);
- $this->out->elementStart('table', array('class' => 'extended-profile'));
- foreach ($section['fields'] as $fieldName => $field) {
- switch ($fieldName) {
- case 'phone':
- case 'im':
- case 'website':
- case 'experience':
- case 'education':
- $this->showMultiple($fieldName, $field);
- break;
- default:
- $this->showExtendedProfileField($fieldName, $field);
- }
- }
- $this->out->elementEnd('table');
- }
- /**
- * Show an extended profile field
- *
- * @param string $name name of the field
- * @param array $field set of key/value pairs for the field
- * @throws Exception
- */
- protected function showExtendedProfileField($name, $field)
- {
- $this->out->elementStart('tr');
- $this->out->element('th', str_replace(' ', '_', strtolower($field['label'])), $field['label']);
- $this->out->elementStart('td');
- if ($this->editable) {
- $this->showEditableField($name, $field);
- } else {
- $this->showFieldValue($name, $field);
- }
- $this->out->elementEnd('td');
- $this->out->elementEnd('tr');
- }
- protected function showMultiple($name, $fields)
- {
- foreach ($fields as $field) {
- $this->showExtendedProfileField($name, $field);
- }
- }
- // XXX: showPhone, showIm and showWebsite all work the same, so
- // combine
- protected function showPhone($name, $field)
- {
- $this->out->elementStart('div', ['class' => 'phone-display']);
- if (!empty($field['value'])) {
- $this->out->text($field['value']);
- if (!empty($field['rel'])) {
- // TRANS: Value between parentheses (phone number, website, or IM address).
- $outtext = sprintf(_m('(%s)'), $field['rel']);
- $this->out->text(' ' . $outtext);
- }
- }
- $this->out->elementEnd('div');
- }
- protected function showIm($name, $field)
- {
- $this->out->elementStart('div', ['class' => 'im-display']);
- if (!empty($field['value'])) {
- $this->out->text($field['value']);
- if (!empty($field['rel'])) {
- // TRANS: Value between parentheses (phone number, website, or IM address).
- $outtext = sprintf(_m('(%s)'), $field['rel']);
- $this->out->text(' ' . $outtext);
- }
- }
- $this->out->elementEnd('div');
- }
- protected function showWebsite($name, $field)
- {
- $this->out->elementStart('div', ['class' => 'website-display']);
- if (!empty($field['value'])) {
- $url = $field['value'];
- $this->out->element('a', [
- 'href' => $url,
- 'class' => 'extended-profile-link',
- 'target' => '_blank',
- ], $url);
- if (!empty($field['rel'])) {
- // TRANS: Value between parentheses (phone number, website, or IM address).
- $outtext = sprintf(_m('(%s)'), $field['rel']);
- $this->out->text(' ' . $outtext);
- }
- }
- $this->out->elementEnd('div');
- }
- protected function showEditableIm($name, $field)
- {
- $index = (int) ($field['index'] ?? 0);
- $id = "extprofile-{$name}-{$index}";
- $rel = $id . '-rel';
- $this->out->elementStart(
- 'div',
- array(
- 'id' => $id . '-edit',
- 'class' => 'im-item'
- )
- );
- $this->out->input(
- $id,
- null,
- ($field['value'] ?? null)
- );
- $this->out->dropdown(
- $id . '-rel',
- 'Type',
- array(
- 'jabber' => 'Jabber',
- 'gtalk' => 'GTalk',
- 'aim' => 'AIM',
- 'yahoo' => 'Yahoo! Messenger',
- 'msn' => 'MSN',
- 'skype' => 'Skype',
- 'other' => 'Other'
- ),
- null,
- false,
- ($field['rel'] ?? null)
- );
- $this->showMultiControls();
- $this->out->elementEnd('div');
- }
- protected function showEditablePhone($name, $field)
- {
- $index = (int) ($field['index'] ?? 0);
- $id = "extprofile-{$name}-{$index}";
- $rel = $id . '-rel';
- $this->out->elementStart(
- 'div',
- array(
- 'id' => $id . '-edit',
- 'class' => 'phone-item'
- )
- );
- $this->out->input(
- $id,
- null,
- ($field['value'] ?? null)
- );
- $this->out->dropdown(
- $id . '-rel',
- 'Type',
- array(
- 'office' => 'Office',
- 'mobile' => 'Mobile',
- 'home' => 'Home',
- 'pager' => 'Pager',
- 'other' => 'Other'
- ),
- null,
- false,
- ($field['rel'] ?? null)
- );
- $this->showMultiControls();
- $this->out->elementEnd('div');
- }
- protected function showEditableWebsite($name, $field)
- {
- $index = (int) ($field['index'] ?? 0);
- $id = "extprofile-{$name}-{$index}";
- $rel = $id . '-rel';
- $this->out->elementStart(
- 'div',
- array(
- 'id' => $id . '-edit',
- 'class' => 'website-item'
- )
- );
- $this->out->input(
- $id,
- null,
- ($field['value'] ?? null)
- );
- $this->out->dropdown(
- $id . '-rel',
- 'Type',
- array(
- 'blog' => 'Blog',
- 'homepage' => 'Homepage',
- 'facebook' => 'Facebook',
- 'linkedin' => 'LinkedIn',
- 'flickr' => 'Flickr',
- 'other' => 'Other',
- 'twitter' => 'Twitter'
- ),
- null,
- false,
- ($field['rel'] ?? null)
- );
- $this->showMultiControls();
- $this->out->elementEnd('div');
- }
- protected function showExperience($name, $field)
- {
- $this->out->elementStart('div', 'experience-item');
- // TRANS: Field label in experience area of extended profile.
- $this->out->element('div', 'label', _m('Company'));
- if (!empty($field['company'])) {
- $this->out->element('div', 'field', $field['company']);
- // TRANS: Field label in extended profile (when did one start a position or education).
- $this->out->element('div', 'label', _m('Start'));
- $this->out->element(
- 'div',
- array('class' => 'field date'),
- date(
- 'j M Y',
- strtotime($field['start'])
- )
- );
- // TRANS: Field label in extended profile (when did one end a position or education).
- $this->out->element('div', 'label', _m('End'));
- $this->out->element(
- 'div',
- array('class' => 'field date'),
- date(
- 'j M Y',
- strtotime($field['end'])
- )
- );
- if ($field['current']) {
- $this->out->element(
- 'div',
- array('class' => 'field current'),
- // TRANS: Field value in experience area of extended profile (one still holds a position).
- _m('(Current)')
- );
- }
- }
- $this->out->elementEnd('div');
- }
- protected function showEditableExperience($name, $field)
- {
- $index = (int) ($field['index'] ?? 0);
- $id = "extprofile-{$name}-{$index}";
- $this->out->elementStart(
- 'div',
- array(
- 'id' => $id . '-edit',
- 'class' => 'experience-item'
- )
- );
- // TRANS: Field label in experience edit area of extended profile (which company does one work for).
- $this->out->element('div', 'label', _m('Company'));
- $this->out->input(
- $id,
- null,
- ($field['company'] ?? null)
- );
- // TRANS: Field label in extended profile (when did one start a position or education).
- $this->out->element('div', 'label', _m('Start'));
- $this->out->input(
- $id . '-start',
- null,
- isset($field['start']) ? date('j M Y', strtotime($field['start'])) : null
- );
- // TRANS: Field label in extended profile (when did one end a position or education).
- $this->out->element('div', 'label', _m('End'));
- $this->out->input(
- $id . '-end',
- null,
- isset($field['end']) ? date('j M Y', strtotime($field['end'])) : null
- );
- $this->out->hidden(
- $id . '-current',
- 'false'
- );
- $this->out->elementStart('div', 'current-checkbox');
- $this->out->checkbox(
- $id . '-current',
- // TRANS: Checkbox label in experience edit area of extended profile (one still works at a company).
- _m('Current'),
- $field['current']
- );
- $this->out->elementEnd('div');
- $this->showMultiControls();
- $this->out->elementEnd('div');
- }
- protected function showEducation($name, $field)
- {
- $this->out->elementStart('div', 'education-item');
- // TRANS: Field label in education area of extended profile.
- $this->out->element('div', 'label', _m('Institution'));
- if (!empty($field['school'])) {
- $this->out->element('div', 'field', $field['school']);
- // TRANS: Field label in extended profile for specifying an academic degree.
- $this->out->element('div', 'label', _m('Degree'));
- $this->out->element('div', 'field', $field['degree']);
- // TRANS: Field label in education area of extended profile.
- $this->out->element('div', 'label', _m('Description'));
- $this->out->element('div', 'field', $field['description']);
- // TRANS: Field label in extended profile (when did one start a position or education).
- $this->out->element('div', 'label', _m('Start'));
- $this->out->element(
- 'div',
- array('class' => 'field date'),
- date(
- 'j M Y',
- strtotime($field['start'])
- )
- );
- // TRANS: Field label in extended profile (when did one end a position or education).
- $this->out->element('div', 'label', _m('End'));
- $this->out->element(
- 'div',
- array('class' => 'field date'),
- date(
- 'j M Y',
- strtotime($field['end'])
- )
- );
- }
- $this->out->elementEnd('div');
- }
- protected function showEditableEducation($name, $field)
- {
- $index = (int) ($field['index'] ?? 0);
- $id = "extprofile-{$name}-{$index}";
- $this->out->elementStart(
- 'div',
- array(
- 'id' => $id . '-edit',
- 'class' => 'education-item'
- )
- );
- // TRANS: Field label in education edit area of extended profile.
- $this->out->element('div', 'label', _m('Institution'));
- $this->out->input(
- $id,
- null,
- ($field['school'] ?? null)
- );
- // TRANS: Field label in extended profile for specifying an academic degree.
- $this->out->element('div', 'label', _m('Degree'));
- $this->out->input(
- $id . '-degree',
- null,
- ($field['degree'] ?? null)
- );
- // TRANS: Field label in education edit area of extended profile.
- $this->out->element('div', 'label', _m('Description'));
- $this->out->textarea(
- $id . '-description',
- null,
- ($field['description'] ?? null)
- );
- // TRANS: Field label in extended profile (when did one start a position or education).
- $this->out->element('div', 'label', _m('Start'));
- $this->out->input(
- $id . '-start',
- null,
- // @todo FIXME: does date format need i18n? If so, should probly be dealt with in core.
- isset($field['start']) ? date('j M Y', strtotime($field['start'])) : null
- );
- // TRANS: Field label in extended profile (when did one end a position or education).
- $this->out->element('div', 'label', _m('End'));
- $this->out->input(
- $id . '-end',
- null,
- // @todo FIXME: does date format need i18n? If so, should probly be dealt with in core.
- isset($field['end']) ? date('j M Y', strtotime($field['end'])) : null
- );
- $this->showMultiControls();
- $this->out->elementEnd('div');
- }
- public function showMultiControls()
- {
- $this->out->element(
- 'a',
- array(
- 'class' => 'remove_row',
- 'href' => 'javascript://',
- 'style' => 'display: none;'
- ),
- '-'
- );
- $this->out->element(
- 'a',
- array(
- 'class' => 'add_row',
- 'href' => 'javascript://',
- 'style' => 'display: none;'
- ),
- // TRANS: Link description in extended profile page to add another profile element.
- _m('Add another item')
- );
- }
- /**
- * Outputs the value of a field
- *
- * @param string $name name of the field
- * @param array $field set of key/value pairs for the field
- */
- protected function showFieldValue($name, $field)
- {
- $type = (string) ($field['type'] ?? '');
- switch ($type) {
- case '':
- case 'text':
- case 'textarea':
- case 'person':
- $this->out->text($this->ext->getTextValue($name) ?? '');
- break;
- case 'custom-text':
- case 'custom-textarea':
- $this->out->text($field['value'] ?? '');
- break;
- case 'date':
- $value = $this->ext->getDateValue($name);
- if (!empty($value)) {
- $this->out->element(
- 'div',
- array('class' => 'field date'),
- date('j M Y', strtotime($value))
- );
- }
- break;
- case 'tags':
- $this->out->text($this->ext->getTags());
- break;
- case 'phone':
- $this->showPhone($name, $field);
- break;
- case 'website':
- $this->showWebsite($name, $field);
- break;
- case 'im':
- $this->showIm($name, $field);
- break;
- case 'experience':
- $this->showExperience($name, $field);
- break;
- case 'education':
- $this->showEducation($name, $field);
- break;
- default:
- $this->out->text("TYPE: $type");
- }
- }
- /**
- * Show an editable version of the field
- *
- * @param string $name name fo the field
- * @param array $field array of key/value pairs for the field
- * @throws Exception
- */
- protected function showEditableField($name, $field)
- {
- $out = $this->out;
- $type = (string) ($field['type'] ?? '');
- $id = "extprofile-" . $name;
- $value = 'placeholder';
- switch ($type) {
- case '':
- case 'text':
- case 'person':
- $out->input($id, null, $this->ext->getTextValue($name));
- break;
- case 'custom-text':
- case 'custom-textarea':
- $out->input($id, null, ($field['value'] ?? null));
- break;
- case 'date':
- $value = $this->ext->getDateValue($name);
- $out->input(
- $id,
- null,
- empty($value) ? null : date('j M Y', strtotime($value))
- );
- break;
- case 'textarea':
- $out->textarea($id, null, $this->ext->getTextValue($name));
- break;
- case 'tags':
- $out->input($id, null, $this->ext->getTags());
- break;
- case 'phone':
- $this->showEditablePhone($name, $field);
- break;
- case 'im':
- $this->showEditableIm($name, $field);
- break;
- case 'website':
- $this->showEditableWebsite($name, $field);
- break;
- case 'experience':
- $this->showEditableExperience($name, $field);
- break;
- case 'education':
- $this->showEditableEducation($name, $field);
- break;
- default:
- // TRANS: Field label for undefined field in extended profile.
- $out->input($id, null, sprintf(_m('TYPE: %s'), $type));
- }
- }
- /**
- * Action elements
- *
- * @return void
- * @throws Exception
- */
- public function formActions()
- {
- $this->out->submit(
- 'save',
- // TRANS: Button text for saving extended profile properties.
- _m('BUTTON', 'Save'),
- 'submit form_action-secondary',
- 'save',
- // TRANS: .
- // TRANS: Button title for saving extended profile properties.
- _m('Save details')
- );
- }
- /**
- * ID of the form
- *
- * @return string ID of the form
- */
- public function id()
- {
- return 'profile-details-' . $this->profile->id;
- }
- /**
- * class of the form
- *
- * @return string of the form class
- */
- public function formClass()
- {
- return 'form_profile_details form_settings';
- }
- /**
- * Action of the form
- *
- * @return string URL of the action
- */
- public function action()
- {
- return common_local_url('profiledetailsettings');
- }
- }
|