]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge branch 'extprofile' into 0.9.x
authorBrion Vibber <brion@pobox.com>
Mon, 28 Feb 2011 18:45:53 +0000 (10:45 -0800)
committerBrion Vibber <brion@pobox.com>
Mon, 28 Feb 2011 18:45:53 +0000 (10:45 -0800)
plugins/ExtendedProfile/ExtendedProfilePlugin.php [new file with mode: 0644]
plugins/ExtendedProfile/Profile_detail.php [new file with mode: 0644]
plugins/ExtendedProfile/extendedprofile.php [new file with mode: 0644]
plugins/ExtendedProfile/extendedprofilewidget.php [new file with mode: 0644]
plugins/ExtendedProfile/profiledetail.css [new file with mode: 0644]
plugins/ExtendedProfile/profiledetailaction.php [new file with mode: 0644]
plugins/ExtendedProfile/profiledetailsettingsaction.php [new file with mode: 0644]

diff --git a/plugins/ExtendedProfile/ExtendedProfilePlugin.php b/plugins/ExtendedProfile/ExtendedProfilePlugin.php
new file mode 100644 (file)
index 0000000..3f541c0
--- /dev/null
@@ -0,0 +1,121 @@
+<?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);
+}
+
+/**
+ * Extra profile bio-like fields
+ *
+ * @package ExtendedProfilePlugin
+ * @maintainer Brion Vibber <brion@status.net>
+ */
+class ExtendedProfilePlugin extends Plugin
+{
+
+    function onPluginVersion(&$versions)
+    {
+        $versions[] = array('name' => 'ExtendedProfile',
+                            'version' => STATUSNET_VERSION,
+                            'author' => 'Brion Vibber',
+                            'homepage' => 'http://status.net/wiki/Plugin:ExtendedProfile',
+                            'rawdescription' =>
+                            _m('UI extensions for additional profile fields.'));
+
+        return true;
+    }
+
+    /**
+     * Autoloader
+     *
+     * Loads our classes if they're requested.
+     *
+     * @param string $cls Class requested
+     *
+     * @return boolean hook return
+     */
+    function onAutoload($cls)
+    {
+        $lower = strtolower($cls);
+        switch ($lower)
+        {
+        case 'extendedprofile':
+        case 'extendedprofilewidget':
+        case 'profiledetailaction':
+        case 'profiledetailsettingsaction':
+            require_once dirname(__FILE__) . '/' . $lower . '.php';
+            return false;
+        case 'profile_detail':
+            require_once dirname(__FILE__) . '/' . ucfirst($lower) . '.php';
+            return false;
+        default:
+            return true;
+        }
+    }
+
+    /**
+     * Add paths to the router table
+     *
+     * Hook for RouterInitialized event.
+     *
+     * @param Net_URL_Mapper $m URL mapper
+     *
+     * @return boolean hook return
+     */
+    function onStartInitializeRouter($m)
+    {
+        $m->connect(':nickname/detail',
+                array('action' => 'profiledetail'),
+                array('nickname' => Nickname::DISPLAY_FMT));
+        $m->connect('settings/profile/detail',
+                array('action' => 'profiledetailsettings'));
+
+        return true;
+    }
+
+    function onCheckSchema()
+    {
+        $schema = Schema::get();
+        $schema->ensureTable('profile_detail', Profile_detail::schemaDef());
+
+        // @hack until key definition support is merged
+        Profile_detail::fixIndexes($schema);
+        return true;
+    }
+
+    function onEndAccountSettingsProfileMenuItem($widget, $menu)
+    {
+        // TRANS: Link title attribute in user account settings menu.
+        $title = _('Change additional profile settings');
+        // TRANS: Link description in user account settings menu.
+        $widget->showMenuItem('profiledetailsettings',_m('Details'),$title);
+        return true;
+    }
+
+    function onEndProfilePageProfileElements(HTMLOutputter $out, Profile $profile) {
+        $user = User::staticGet('id', $profile->id);
+        if ($user) {
+            $url = common_local_url('profiledetail', array('nickname' => $user->nickname));
+            $out->element('a', array('href' => $url), _m('More details...'));
+        }
+        return;
+    }
+
+}
diff --git a/plugins/ExtendedProfile/Profile_detail.php b/plugins/ExtendedProfile/Profile_detail.php
new file mode 100644 (file)
index 0000000..6fd96cc
--- /dev/null
@@ -0,0 +1,150 @@
+<?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);
+}
+
+class Profile_detail extends Memcached_DataObject
+{
+    public $__table = 'submirror';
+
+    public $id;
+
+    public $profile_id;
+    public $field;
+    public $field_index; // relative ordering of multiple values in the same field
+
+    public $value; // primary text value
+    public $rel; // detail for some field types; eg "home", "mobile", "work" for phones or "aim", "irc", "xmpp" for IM
+    public $ref_profile; // for people types, allows pointing to a known profile in the system
+
+    public $created;
+    public $modified;
+
+    public /*static*/ function staticGet($k, $v=null)
+    {
+        return parent::staticGet(__CLASS__, $k, $v);
+    }
+
+    /**
+     * return table definition for DB_DataObject
+     *
+     * DB_DataObject needs to know something about the table to manipulate
+     * instances. This method provides all the DB_DataObject needs to know.
+     *
+     * @return array array of column definitions
+     */
+
+    function table()
+    {
+        return array('id' =>  DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
+
+                     'profile_id' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
+                     'field' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
+                     'field_index' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
+
+                     'value' => DB_DATAOBJECT_STR,
+                     'rel' => DB_DATAOBJECT_STR,
+                     'ref_profile' => DB_DATAOBJECT_ID,
+
+                     'created' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL,
+                     'modified' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL);
+    }
+
+    static function schemaDef()
+    {
+        // @fixme need a reverse key on (subscribed, subscriber) as well
+        return array(new ColumnDef('id', 'integer',
+                                   null, false, 'PRI'),
+
+                     // @fixme need a unique index on these three
+                     new ColumnDef('profile_id', 'integer',
+                                   null, false),
+                     new ColumnDef('field', 'varchar',
+                                   16, false),
+                     new ColumnDef('field_index', 'integer',
+                                   null, false),
+
+                     new ColumnDef('value', 'text',
+                                   null, true),
+                     new ColumnDef('rel', 'varchar',
+                                   16, true),
+                     new ColumnDef('ref_profile', 'integer',
+                                   null, true),
+
+                     new ColumnDef('created', 'datetime',
+                                   null, false),
+                     new ColumnDef('modified', 'datetime',
+                                   null, false));
+    }
+
+    /**
+     * Temporary hack to set up the compound index, since we can't do
+     * it yet through regular Schema interface. (Coming for 1.0...)
+     *
+     * @param Schema $schema
+     * @return void
+     */
+    static function fixIndexes($schema)
+    {
+        try {
+            // @fixme this won't be a unique index... SIGH
+            $schema->createIndex('profile_detail', array('profile_id', 'field', 'field_index'));
+        } catch (Exception $e) {
+            common_log(LOG_ERR, __METHOD__ . ': ' . $e->getMessage());
+        }
+    }
+
+    /**
+     * return key definitions for DB_DataObject
+     *
+     * DB_DataObject needs to know about keys that the table has; this function
+     * defines them.
+     *
+     * @return array key definitions
+     */
+
+    function keys()
+    {
+        return array_keys($this->keyTypes());
+    }
+
+    /**
+     * return key definitions for Memcached_DataObject
+     *
+     * Our caching system uses the same key definitions, but uses a different
+     * method to get them.
+     *
+     * @return array key definitions
+     */
+
+    function keyTypes()
+    {
+        // @fixme keys
+        // need a sane key for reverse lookup too
+        return array('id' => 'K');
+    }
+
+    function sequenceKey()
+    {
+        return array('id', true);
+    }
+
+}
diff --git a/plugins/ExtendedProfile/extendedprofile.php b/plugins/ExtendedProfile/extendedprofile.php
new file mode 100644 (file)
index 0000000..7f69f90
--- /dev/null
@@ -0,0 +1,139 @@
+<?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);
+}
+
+class ExtendedProfile
+{
+    function __construct(Profile $profile)
+    {
+        $this->profile = $profile;
+        $this->sections = $this->getSections();
+        $this->fields = $this->loadFields();
+    }
+
+    function loadFields()
+    {
+        $detail = new Profile_detail();
+        $detail->profile_id = $this->profile->id;
+        $detail->find();
+        
+        while ($detail->get()) {
+            $fields[$detail->field][] = clone($detail);
+        }
+        return $fields;
+    }
+
+    function getSections()
+    {
+        return array(
+            'basic' => array(
+                'label' => _m('Personal'),
+                'fields' => array(
+                    'fullname' => array(
+                        'label' => _m('Full name'),
+                        'profile' => 'fullname',
+                        'vcard' => 'fn',
+                    ),
+                    'title' => array(
+                        'label' => _m('Title'),
+                        'vcard' => 'title',
+                    ),
+                    'manager' => array(
+                        'label' => _m('Manager'),
+                        'type' => 'person',
+                        'vcard' => 'x-manager',
+                    ),
+                    'location' => array(
+                        'label' => _m('Location'),
+                        'profile' => 'location'
+                    ),
+                    'bio' => array(
+                        'label' => _m('Bio'),
+                        'type' => 'textarea',
+                        'profile' => 'bio',
+                    ),
+                    'tags' => array(
+                        'label' => _m('Tags'),
+                        'type' => 'tags',
+                        'profile' => 'tags',
+                    ),
+                ),
+            ),
+            'contact' => array(
+                'label' => _m('Contact'),
+                'fields' => array(
+                    'phone' => array(
+                        'label' => _m('Phone'),
+                        'type' => 'phone',
+                        'multi' => true,
+                        'vcard' => 'tel',
+                    ),
+                    'im' => array(
+                        'label' => _m('IM'),
+                        'type' => 'im',
+                        'multi' => true,
+                    ),
+                    'website' => array(
+                        'label' => _m('Websites'),
+                        'type' => 'website',
+                        'multi' => true,
+                    ),
+                ),
+            ),
+            'personal' => array(
+                'label' => _m('Personal'),
+                'fields' => array(
+                    'birthday' => array(
+                        'label' => _m('Birthday'),
+                        'type' => 'date',
+                        'vcard' => 'bday',
+                    ),
+                    'spouse' => array(
+                        'label' => _m('Spouse\'s name'),
+                        'vcard' => 'x-spouse',
+                    ),
+                    'kids' => array(
+                        'label' => _m('Kids\' names')
+                    ),
+                ),
+            ),
+            'experience' => array(
+                'label' => _m('Work experience'),
+                'fields' => array(
+                    'experience' => array(
+                        'type' => 'experience',
+                        'label' => _m('Employer'),
+                    ),
+                ),
+            ),
+            'education' => array(
+                'label' => _m('Education'),
+                'fields' => array(
+                    'education' => array(
+                        'type' => 'education',
+                        'label' => _m('Institution'),
+                    ),
+                ),
+            ),
+        );
+    }
+}
diff --git a/plugins/ExtendedProfile/extendedprofilewidget.php b/plugins/ExtendedProfile/extendedprofilewidget.php
new file mode 100644 (file)
index 0000000..bf9b405
--- /dev/null
@@ -0,0 +1,102 @@
+<?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);
+}
+
+class ExtendedProfileWidget extends Widget
+{
+    const EDITABLE=true;
+
+    protected $profile;
+    protected $ext;
+
+    public function __construct(XMLOutputter $out=null, Profile $profile=null, $editable=false)
+    {
+        parent::__construct($out);
+
+        $this->profile = $profile;
+        $this->ext = new ExtendedProfile($this->profile);
+
+        $this->editable = $editable;
+    }
+
+    public function show()
+    {
+        $sections = $this->ext->getSections();
+        foreach ($sections as $name => $section) {
+            $this->showExtendedProfileSection($name, $section);
+        }
+    }
+
+    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) {
+            $this->showExtendedProfileField($fieldName, $field);
+        }
+        $this->out->elementEnd('table');
+    }
+
+    protected function showExtendedProfileField($name, $field)
+    {
+        $this->out->elementStart('tr');
+
+        $this->out->element('th', null, $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 showFieldValue($name, $field)
+    {
+        $this->out->text($name);
+    }
+
+    protected function showEditableField($name, $field)
+    {
+        $out = $this->out;
+        //$out = new HTMLOutputter();
+        // @fixme
+        $type = strval(@$field['type']);
+        $id = "extprofile-" . $name;
+        $value = 'placeholder';
+
+        switch ($type) {
+            case '':
+            case 'text':
+                $out->input($id, null, $value);
+                break;
+            case 'textarea':
+                $out->textarea($id, null, $value);
+                break;
+            default:
+                $out->input($id, null, "TYPE: $type");
+        }
+    }
+}
diff --git a/plugins/ExtendedProfile/profiledetail.css b/plugins/ExtendedProfile/profiledetail.css
new file mode 100644 (file)
index 0000000..836b647
--- /dev/null
@@ -0,0 +1,22 @@
+/* Note the #content is only needed to override weird crap in default styles */
+
+#content table.extended-profile {
+    width: 100%;
+    border-collapse: separate;
+    border-spacing: 8px;
+}
+#content table.extended-profile th {
+    color: #777;
+    background-color: #eee;
+    width: 150px;
+
+    padding-top: 0; /* override bizarre theme defaults */
+
+    text-align: right;
+    padding-right: 8px;
+}
+#content table.extended-profile td {
+    padding: 0; /* override bizarre theme defaults */
+
+    padding-left: 8px;
+}
\ No newline at end of file
diff --git a/plugins/ExtendedProfile/profiledetailaction.php b/plugins/ExtendedProfile/profiledetailaction.php
new file mode 100644 (file)
index 0000000..a4bb129
--- /dev/null
@@ -0,0 +1,71 @@
+<?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);
+}
+
+class ProfileDetailAction extends ProfileAction
+{
+    function isReadOnly($args)
+    {
+        return true;
+    }
+
+    function title()
+    {
+        return $this->profile->getFancyName();
+    }
+
+    function showLocalNav()
+    {
+        $nav = new PersonalGroupNav($this);
+        $nav->show();
+    }
+
+    function showStylesheets() {
+        parent::showStylesheets();
+        $this->cssLink('plugins/ExtendedProfile/profiledetail.css');
+        return true;
+    }
+
+    function handle($args)
+    {
+        $this->showPage();
+    }
+
+    function showContent()
+    {
+        $cur = common_current_user();
+        if ($cur && $cur->id == $this->profile->id) { // your own page
+            $this->elementStart('div', 'entity_actions');
+            $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->elementEnd('li');
+            $this->elementEnd('div');
+        }
+
+        $widget = new ExtendedProfileWidget($this, $this->profile);
+        $widget->show();
+    }
+}
diff --git a/plugins/ExtendedProfile/profiledetailsettingsaction.php b/plugins/ExtendedProfile/profiledetailsettingsaction.php
new file mode 100644 (file)
index 0000000..77d755c
--- /dev/null
@@ -0,0 +1,63 @@
+<?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);
+}
+
+class ProfileDetailSettingsAction extends AccountSettingsAction
+{
+
+    function title()
+    {
+        return _m('Extended profile settings');
+    }
+
+    /**
+     * Instructions for use
+     *
+     * @return instructions for use
+     */
+    function getInstructions()
+    {
+        // TRANS: Usage instructions for profile settings.
+        return _('You can update your personal profile info here '.
+                 'so people know more about you.');
+    }
+
+    function showStylesheets() {
+        parent::showStylesheets();
+        $this->cssLink('plugins/ExtendedProfile/profiledetail.css');
+        return true;
+    }
+
+    function handle($args)
+    {
+        $this->showPage();
+    }
+
+    function showContent()
+    {
+        $cur = common_current_user();
+        $profile = $cur->getProfile();
+
+        $widget = new ExtendedProfileWidget($this, $profile, ExtendedProfileWidget::EDITABLE);
+        $widget->show();
+    }
+}