]> git.mxchange.org Git - friendica.git/commitdiff
Merge pull request #8179 from MrPetovan/bug/notices
authorPhilipp <admin+Github@philipp.info>
Sun, 26 Jan 2020 22:10:56 +0000 (23:10 +0100)
committerGitHub <noreply@github.com>
Sun, 26 Jan 2020 22:10:56 +0000 (23:10 +0100)
Various notice fixes

185 files changed:
boot.php
composer.json
composer.lock
database.sql
doc/API-Friendica.md
doc/Profiles.md [deleted file]
doc/de/Account-Basics.md
doc/de/Home.md
doc/de/Profiles.md [deleted file]
include/api.php
include/conversation.php
include/enotify.php
mod/cal.php
mod/display.php
mod/events.php
mod/item.php
mod/msearch.php
mod/network.php
mod/notes.php
mod/notifications.php [deleted file]
mod/photos.php
mod/ping.php
mod/poco.php
mod/profiles.php [deleted file]
mod/profperm.php [deleted file]
mod/regmod.php
mod/settings.php
mod/update_profile.php [deleted file]
mod/videos.php
src/BaseCollection.php
src/BaseModel.php
src/BaseRepository.php
src/Collection/Notifies.php [new file with mode: 0644]
src/Collection/ProfileFields.php [new file with mode: 0644]
src/Content/ContactSelector.php
src/Content/Feature.php
src/Content/Nav.php
src/Content/Widget.php
src/Core/UserImport.php
src/DI.php
src/Factory/Notification/Introduction.php [new file with mode: 0644]
src/Factory/Notification/Notification.php [new file with mode: 0644]
src/Model/Contact.php
src/Model/Notify.php
src/Model/Profile.php
src/Model/ProfileField.php [new file with mode: 0644]
src/Model/User.php
src/Module/BaseNotifications.php [new file with mode: 0644]
src/Module/BaseProfile.php [new file with mode: 0644]
src/Module/BaseSettingsModule.php
src/Module/Contact.php
src/Module/Notifications/Introductions.php [new file with mode: 0644]
src/Module/Notifications/Notification.php [new file with mode: 0644]
src/Module/Notifications/Notifications.php [new file with mode: 0644]
src/Module/Notifications/Notify.php [deleted file]
src/Module/Profile.php [deleted file]
src/Module/Profile/Contacts.php
src/Module/Profile/Index.php [new file with mode: 0644]
src/Module/Profile/Profile.php [new file with mode: 0644]
src/Module/Profile/Status.php [new file with mode: 0644]
src/Module/Settings/Profile/Index.php [new file with mode: 0644]
src/Module/Settings/UserExport.php
src/Module/Update/Profile.php [new file with mode: 0644]
src/Object/EMail/IEmail.php [new file with mode: 0644]
src/Object/EMail/ItemCCEMail.php [new file with mode: 0644]
src/Object/Email.php [new file with mode: 0644]
src/Object/Notification/Introduction.php [new file with mode: 0644]
src/Object/Notification/Notification.php [new file with mode: 0644]
src/Protocol/ActivityPub/Transmitter.php
src/Protocol/DFRN.php
src/Protocol/Diaspora.php
src/Protocol/OStatus.php
src/Repository/Notify.php [new file with mode: 0644]
src/Repository/PermissionSet.php
src/Repository/ProfileField.php [new file with mode: 0644]
src/Util/Emailer.php
src/Worker/Directory.php
static/dbstructure.config.php
static/routes.config.php
tests/src/App/RouterTest.php
update.php
view/global.css
view/js/main.js
view/js/module/settings/profile/index.js [new file with mode: 0644]
view/templates/contact_edit.tpl
view/templates/intros.tpl [deleted file]
view/templates/nav.tpl
view/templates/netfriend.tpl [deleted file]
view/templates/notifications.tpl [deleted file]
view/templates/notifications/attend_item.tpl [new file with mode: 0644]
view/templates/notifications/comments_item.tpl [new file with mode: 0644]
view/templates/notifications/dislikes_item.tpl [new file with mode: 0644]
view/templates/notifications/friends_item.tpl [new file with mode: 0644]
view/templates/notifications/intros.tpl [new file with mode: 0644]
view/templates/notifications/likes_item.tpl [new file with mode: 0644]
view/templates/notifications/netfriend.tpl [new file with mode: 0644]
view/templates/notifications/network_item.tpl [new file with mode: 0644]
view/templates/notifications/notification.tpl [new file with mode: 0644]
view/templates/notifications/notifications.tpl [new file with mode: 0644]
view/templates/notifications/posts_item.tpl [new file with mode: 0644]
view/templates/notifications/suggestions.tpl [new file with mode: 0644]
view/templates/notifications_attend_item.tpl [deleted file]
view/templates/notifications_comments_item.tpl [deleted file]
view/templates/notifications_dislikes_item.tpl [deleted file]
view/templates/notifications_friends_item.tpl [deleted file]
view/templates/notifications_likes_item.tpl [deleted file]
view/templates/notifications_network_item.tpl [deleted file]
view/templates/notifications_posts_item.tpl [deleted file]
view/templates/notify.tpl [deleted file]
view/templates/profed_head.tpl [deleted file]
view/templates/profile-hide-friends.tpl [deleted file]
view/templates/profile-hide-wall.tpl [deleted file]
view/templates/profile-in-directory.tpl [deleted file]
view/templates/profile-in-netdir.tpl [deleted file]
view/templates/profile/advanced.tpl [deleted file]
view/templates/profile/index.tpl [new file with mode: 0644]
view/templates/profile_edit.tpl [deleted file]
view/templates/profile_edlink.tpl [deleted file]
view/templates/profile_entry.tpl [deleted file]
view/templates/profile_listing_header.tpl [deleted file]
view/templates/settings/profile/field/edit.tpl [new file with mode: 0644]
view/templates/settings/profile/hide-friends.tpl [new file with mode: 0644]
view/templates/settings/profile/index.tpl [new file with mode: 0644]
view/templates/settings/profile/index_head.tpl [new file with mode: 0644]
view/templates/settings/profile/link.tpl [new file with mode: 0644]
view/templates/settings/settings.tpl
view/templates/suggestions.tpl [deleted file]
view/templates/welcome.tpl
view/theme/duepuntozero/deriv/darkzero.css
view/theme/duepuntozero/style.css
view/theme/duepuntozero/templates/nav.tpl
view/theme/frio/css/style.css
view/theme/frio/scheme/plusminus.css
view/theme/frio/templates/contact_edit.tpl
view/theme/frio/templates/intros.tpl [deleted file]
view/theme/frio/templates/nav.tpl
view/theme/frio/templates/notifications.tpl [deleted file]
view/theme/frio/templates/notifications/attend_item.tpl [new file with mode: 0644]
view/theme/frio/templates/notifications/comments_item.tpl [new file with mode: 0644]
view/theme/frio/templates/notifications/dislikes_item.tpl [new file with mode: 0644]
view/theme/frio/templates/notifications/friends_item.tpl [new file with mode: 0644]
view/theme/frio/templates/notifications/intros.tpl [new file with mode: 0644]
view/theme/frio/templates/notifications/likes_item.tpl [new file with mode: 0644]
view/theme/frio/templates/notifications/network_item.tpl [new file with mode: 0644]
view/theme/frio/templates/notifications/notifications.tpl [new file with mode: 0644]
view/theme/frio/templates/notifications/notify.tpl [new file with mode: 0644]
view/theme/frio/templates/notifications/posts_item.tpl [new file with mode: 0644]
view/theme/frio/templates/notifications/suggestions.tpl [new file with mode: 0644]
view/theme/frio/templates/notifications_attend_item.tpl [deleted file]
view/theme/frio/templates/notifications_comments_item.tpl [deleted file]
view/theme/frio/templates/notifications_dislikes_item.tpl [deleted file]
view/theme/frio/templates/notifications_friends_item.tpl [deleted file]
view/theme/frio/templates/notifications_likes_item.tpl [deleted file]
view/theme/frio/templates/notifications_network_item.tpl [deleted file]
view/theme/frio/templates/notifications_posts_item.tpl [deleted file]
view/theme/frio/templates/notify.tpl [deleted file]
view/theme/frio/templates/profile/advanced.tpl [deleted file]
view/theme/frio/templates/profile_edit.tpl [deleted file]
view/theme/frio/templates/profile_entry.tpl [deleted file]
view/theme/frio/templates/profile_listing_header.tpl [deleted file]
view/theme/frio/templates/settings/profile/field/edit.tpl [new file with mode: 0644]
view/theme/frio/templates/settings/profile/index.tpl [new file with mode: 0644]
view/theme/frio/templates/settings/settings.tpl
view/theme/frio/templates/suggestions.tpl [deleted file]
view/theme/frio/templates/wall_thread.tpl
view/theme/quattro/dark/style.css
view/theme/quattro/green/style.css
view/theme/quattro/lilac/style.css
view/theme/quattro/quattro.less
view/theme/quattro/templates/nav.tpl
view/theme/smoothly/style.css
view/theme/smoothly/templates/nav.tpl
view/theme/vier/dark.css
view/theme/vier/plus.css
view/theme/vier/plusminus.css
view/theme/vier/shadow.css
view/theme/vier/style.css
view/theme/vier/templates/contact_edit.tpl
view/theme/vier/templates/nav.tpl
view/theme/vier/templates/profile/advanced.tpl [deleted file]
view/theme/vier/templates/profile_edit.tpl [deleted file]
view/theme/vier/templates/profile_edlink.tpl [deleted file]
view/theme/vier/templates/settings/profile/index.tpl [new file with mode: 0644]
view/theme/vier/templates/settings/profile/link.tpl [new file with mode: 0644]
view/theme/vier/theme.php

index 4e1249e197ce14bfb2d2f6bc58c3a43ea9ecafdc..2bcbb4ebdd8eb745e8b3c3f622787a8750247831 100644 (file)
--- a/boot.php
+++ b/boot.php
@@ -355,7 +355,7 @@ function feed_birthday($uid, $tz)
                $tz = 'UTC';
        }
 
-       $profile = DBA::selectFirst('profile', ['dob'], ['is-default' => true, 'uid' => $uid]);
+       $profile = DBA::selectFirst('profile', ['dob'], ['uid' => $uid]);
        if (DBA::isResult($profile)) {
                $tmp_dob = substr($profile['dob'], 5);
                if (intval($tmp_dob)) {
index e372547aac5b9a46ebb9406ca291fcb887ad783f..915c2b08ccc0fe8e52c032f8efea9bfc905aa498 100644 (file)
@@ -52,6 +52,7 @@
                "bower-asset/dompurify": "^1.0",
                "bower-asset/perfect-scrollbar": "^0.6",
                "bower-asset/vue": "^2.6",
+               "npm-asset/es-jquery-sortable": "^0.9.13",
                "npm-asset/jquery": "^2.0",
                "npm-asset/jquery-colorbox": "^1.6",
                "npm-asset/jquery-datetimepicker": "^2.5",
index 3a4670b20af0e42152073d06c0cef3871a1502cc..c8fa900ac0e16a9bf25fcc1734f7206a610c394f 100644 (file)
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "34ad225ce21474eb84ce78047d9f2c01",
+    "content-hash": "6659cc3edcbdb9d706019810788d8dc3",
     "packages": [
         {
             "name": "asika/simple-console",
             ],
             "time": "2018-01-03T13:39:39+00:00"
         },
+        {
+            "name": "npm-asset/es-jquery-sortable",
+            "version": "0.9.13-patch2",
+            "dist": {
+                "type": "tar",
+                "url": "https://registry.npmjs.org/es-jquery-sortable/-/es-jquery-sortable-0.9.13-patch2.tgz",
+                "shasum": "a4db16d133fbce1bcd1543c98279902a6b0812a3"
+            },
+            "require": {
+                "npm-asset/jquery": ">=2.1.2,<3.0.0"
+            },
+            "type": "npm-asset-library",
+            "extra": {
+                "npm-asset-bugs": {
+                    "url": "https://github.com/johnny/jquery-sortable/issues"
+                },
+                "npm-asset-main": "./source/js/jquery-sortable.js",
+                "npm-asset-directories": [],
+                "npm-asset-repository": {
+                    "type": "git",
+                    "url": "git+https://github.com/johnny/jquery-sortable.git"
+                },
+                "npm-asset-scripts": {
+                    "test": "echo \"Error: no test specified\" && exit 1"
+                }
+            },
+            "license": [
+                "BSD-3"
+            ],
+            "authors": [
+                ""
+            ],
+            "description": "jquery plugin for sortable, nestable lists",
+            "homepage": "https://github.com/johnny/jquery-sortable",
+            "keywords": [
+                "drag",
+                "dragging",
+                "sort",
+                "sortable",
+                "sorting"
+            ],
+            "time": "2019-11-20T03:55:51+00:00"
+        },
         {
             "name": "npm-asset/ev-emitter",
             "version": "1.1.1",
index 8db6c1d6f02725d461550d0a12a960e80452e884..78c71efeefe54250cc35b9407d9b0f72c8f7fde4 100644 (file)
@@ -1,6 +1,6 @@
 -- ------------------------------------------
 -- Friendica 2020.03-dev (Dalmatian Bellflower)
--- DB_UPDATE_VERSION 1330
+-- DB_UPDATE_VERSION 1332
 -- ------------------------------------------
 
 
@@ -233,7 +233,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
        `reason` text COMMENT '',
        `closeness` tinyint unsigned NOT NULL DEFAULT 99 COMMENT '',
        `info` mediumtext COMMENT '',
-       `profile-id` int unsigned NOT NULL DEFAULT 0 COMMENT '',
+       `profile-id` int unsigned COMMENT 'Deprecated',
        `bdyear` varchar(4) NOT NULL DEFAULT '' COMMENT '',
        `bd` date NOT NULL DEFAULT '0001-01-01' COMMENT '',
        `notify_new_posts` boolean NOT NULL DEFAULT '0' COMMENT '',
@@ -995,8 +995,8 @@ CREATE TABLE IF NOT EXISTS `process` (
 CREATE TABLE IF NOT EXISTS `profile` (
        `id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
        `uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner User id',
-       `profile-name` varchar(255) NOT NULL DEFAULT '' COMMENT 'Name of the profile',
-       `is-default` boolean NOT NULL DEFAULT '0' COMMENT 'Mark this profile as default profile',
+       `profile-name` varchar(255) COMMENT 'Deprecated',
+       `is-default` boolean COMMENT 'Deprecated',
        `hide-friends` boolean NOT NULL DEFAULT '0' COMMENT 'Hide friend list from viewers of this profile',
        `name` varchar(255) NOT NULL DEFAULT '' COMMENT '',
        `pdesc` varchar(255) NOT NULL DEFAULT '' COMMENT 'Title or description',
@@ -1006,29 +1006,29 @@ CREATE TABLE IF NOT EXISTS `profile` (
        `region` varchar(255) NOT NULL DEFAULT '' COMMENT '',
        `postal-code` varchar(32) NOT NULL DEFAULT '' COMMENT '',
        `country-name` varchar(255) NOT NULL DEFAULT '' COMMENT '',
-       `hometown` varchar(255) NOT NULL DEFAULT '' COMMENT '',
-       `gender` varchar(32) NOT NULL DEFAULT '' COMMENT '',
-       `marital` varchar(255) NOT NULL DEFAULT '' COMMENT '',
-       `with` text COMMENT '',
-       `howlong` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
-       `sexual` varchar(255) NOT NULL DEFAULT '' COMMENT '',
-       `politic` varchar(255) NOT NULL DEFAULT '' COMMENT '',
-       `religion` varchar(255) NOT NULL DEFAULT '' COMMENT '',
+       `hometown` varchar(255) COMMENT 'Deprecated',
+       `gender` varchar(32) COMMENT 'Deprecated',
+       `marital` varchar(255) COMMENT 'Deprecated',
+       `with` text COMMENT 'Deprecated',
+       `howlong` datetime COMMENT 'Deprecated',
+       `sexual` varchar(255) COMMENT 'Deprecated',
+       `politic` varchar(255) COMMENT 'Deprecated',
+       `religion` varchar(255) COMMENT 'Deprecated',
        `pub_keywords` text COMMENT '',
        `prv_keywords` text COMMENT '',
-       `likes` text COMMENT '',
-       `dislikes` text COMMENT '',
-       `about` text COMMENT '',
-       `summary` varchar(255) NOT NULL DEFAULT '' COMMENT '',
-       `music` text COMMENT '',
-       `book` text COMMENT '',
-       `tv` text COMMENT '',
-       `film` text COMMENT '',
-       `interest` text COMMENT '',
-       `romance` text COMMENT '',
-       `work` text COMMENT '',
-       `education` text COMMENT '',
-       `contact` text COMMENT '',
+       `likes` text COMMENT 'Deprecated',
+       `dislikes` text COMMENT 'Deprecated',
+       `about` text COMMENT 'Deprecated',
+       `summary` varchar(255) COMMENT 'Deprecated',
+       `music` text COMMENT 'Deprecated',
+       `book` text COMMENT 'Deprecated',
+       `tv` text COMMENT 'Deprecated',
+       `film` text COMMENT 'Deprecated',
+       `interest` text COMMENT 'Deprecated',
+       `romance` text COMMENT 'Deprecated',
+       `work` text COMMENT 'Deprecated',
+       `education` text COMMENT 'Deprecated',
+       `contact` text COMMENT 'Deprecated',
        `homepage` varchar(255) NOT NULL DEFAULT '' COMMENT '',
        `xmpp` varchar(255) NOT NULL DEFAULT '' COMMENT '',
        `photo` varchar(255) NOT NULL DEFAULT '' COMMENT '',
@@ -1053,6 +1053,25 @@ CREATE TABLE IF NOT EXISTS `profile_check` (
         PRIMARY KEY(`id`)
 ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='DFRN remote auth use';
 
+--
+-- TABLE profile_field
+--
+CREATE TABLE IF NOT EXISTS `profile_field` (
+    `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'sequential ID',
+    `uid` mediumint(8) unsigned NOT NULL DEFAULT 0 COMMENT 'Owner user id',
+    `psid` int(10) unsigned DEFAULT NULL COMMENT 'ID of the permission set of this profile field - 0 = public',
+    `name` varchar(255) NOT NULL DEFAULT '' COMMENT 'Name of the field',
+    `value` text COMMENT 'Value of the field',
+    `order` mediumint(8) unsigned NOT NULL DEFAULT 1 COMMENT 'Field ordering per user',
+    `label` varchar(255) NOT NULL DEFAULT '' COMMENT 'Label of the field',
+    `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
+    `edited` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
+    PRIMARY KEY (`id`),
+    KEY `uid` (`uid`),
+    KEY `psid` (`psid`),
+    KEY `order` (`order`)
+) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Custom profile fields';
+
 --
 -- TABLE push_subscriber
 --
index 76440600c43b8d24b18a44f1918fb2193dea5462..84467430aea878385a086a05ed06ccd8df24a96d 100644 (file)
@@ -655,7 +655,6 @@ Returns the [Profile](help/API-Entities#Profile) data of all profiles or a singl
 
 On success: Array of:
 
-* `multi_profiles`: true if user has activated multi_profiles
 * `global_dir`: URL of the global directory set in server settings
 * `friendica_owner`: user data of the authenticated user
 * `profiles`: array of the profile data
diff --git a/doc/Profiles.md b/doc/Profiles.md
deleted file mode 100644 (file)
index aceb94d..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-Profiles
-========
-
-* [Home](help)
-
-Friendica has unlimited profiles.
-You may use different profiles to present different aspects of yourself to different audiences.
-
-Default / public profile
----
-You always have a profile known as your "default" or "public" profile.
-This profile is always available to the general public and usually cannot be hidden.
-You may, and probably should restrict the personal information you make available on your public profile.
-
-That said, if you want other friends to be able to find you, it helps to have the following information in your public profile:
-
-* Your real name
-* A photo of **you**
-* Your location, preferably at least the country. 
-
-In addition, if you'd like to meet people that share some general interests with you, add some "Public Keywords" to your profile.
-Such as "music, linux, photography" or whatever.
-You can add as many keywords as you like. 
-
-Your default or public profile is also shown to contacts on other networks, since they do not have the ability to view your private profiles.
-Only members of the Friendica network can see alternate/ private profiles.
-
-Alternate/ private profiles
----
-To create an alternate profile, select "Profiles" from the menu of your Friendica site.
-You may edit an existing profile, change the profile photo, or create a new profile.
-You may also "clone" your existing profile if you only wish to change a few items but don't wish to enter all the information again. 
-
-To assign a profile to specific persons, select the person from your "Contacts" page and click the pencil "Edit" icon.
-You will find a dropdown box listing the various profiles available.
-If this box is not selectable, the person is not in a supported network and cannot be assigned a specific profile.
-
-Once a profile has been selected, when the person views your profile from one of the "magic profile links" on their site, they will see the private profile you have assigned.
-If they are not logged into their site or view your profile from elsewhere, they will see your public profile. 
-
-A magic profile link is indicated by a special cursor when hovering over a contact's name or photo.
-Currently this cursor is a hand next to a small padlock.
-These magic cursors indicate that by following the link, you are able to access special areas of the other person's pages which are only available to friends and may not be available to the general public.
-
-You may also discover that (assuming you have the proper permissions) you may be able to post directly on the other person's profile (often called a "wall-to-wall" post).
-You may also be able to comment directly on posts from while visiting the other person's profile page. 
-
-There are two settings which allow you to publish your profile to a directory and ensure that it can be found by others.
-You can change these through settings on the "Settings" page.
-One setting allows you to publish your profile in the site directory of this Friendica server.
-Another option (this may have been disabled by the site admin) allows you to publish your profile in a [Global Directory](Making-Friends.md#the-directories).
-
-If you do not wish to be visible to any of these directories, do not published your profile.   
-
-Although you may have multiple profiles, you only have one profile photo.
-This is intentional; it avoids confusion by potentially seeing different profile pictures of a contact depending on what website you visit or conversation you participate in.
-You can always can use the free text information boxes within a profile such as "Tell us about yourself" and link other photos for yourself.
-
-Keywords and Directory Search
----
-On the site Directory page, you may search for people with published profiles who are on this site.
-The search is typically for your nickname or part of your full name.
-However this search will also match against other profile fields - such as gender, location, "about", work, and education.
-You may also include "Keywords" in your default profile - which may be used to search for common interests with other members.
-You have two sets of keywords available - public and private.
-Private keywords are *not* visible on your profile, but will bring up your profile when matched in a search of the site directory.
-Public keywords are used in the friend suggestion tool and although they aren't readily visible, they may be seen by viewing the HTML of your profile page.
-
-Directory searches are also able to use "boolean" logic so that you can search for "+lesbian +Florida" and find those who's sexual preference (or keywords) contain the world "lesbian" and that live in Florida.
-See the section on "Topical Tags" on the [Tags-and-Mentions](help/Tags-and-Mentions) page for more information on performing boolean searches. 
-
-On your Contacts page is a link to "Find People with Shared Interests" (unless your site administrator has disabled the global directory).
-This will combine both your public and private keywords, and find people in the global directory who have matching and/or similar keywords.
-Private keywords are not identified or stored on the global directory.
-The more keywords you provide, the more relevant the search results that are returned.
-These are sorted by relevance.
-You may discover that you are the first person on the list - because you are very likely the most relevant match for your keywords in the directory.
index 193835f5a9f3e33c02f0b9c45003a4b34258b7f6..81ce68c0415c9cce3b67e084b1b485812a341a06 100644 (file)
@@ -109,8 +109,6 @@ Ein ['Tipp für neue Mitglieder'](newmember)-Link zeigt sich in den ersten beide
 
 ## Schau Dir ebenfalls folgende Seiten an
 
-* [Profile](help/Profiles)
-
 * [Gruppen und Privatssphäre](help/Groups-and-Privacy)
 
 * [Account löschen](help/Remove-Account)
index 536bff72013add754b2dda12218e3d94f7bcd7c8..d008b90c36dc46e06d28b31759b0af6d31801024 100644 (file)
@@ -9,7 +9,6 @@ Friendica - Dokumentation und Ressourcen
        * [Beiträge erstellen](help/Text_editor)
        * [Referenz der BBCode Elemente](help/BBCode)
        * [Beiträge kommentieren, einordnen und löschen](help/Text_comment)
-       * [Profile](help/Profiles)
        * [Referenz der Accesskeys](help/Accesskeys)
     * [Veranstaltungen](help/events)
 * Du und andere Nutzer
diff --git a/doc/de/Profiles.md b/doc/de/Profiles.md
deleted file mode 100644 (file)
index 311f1c7..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-Profile
-========
-
-* [Zur Startseite der Hilfe](help)
-
-Mit Friendica kann eine unbegrenzte Anzahl an Profilen angelegt werden. 
-Du kannst verschiedene Profile nutzen, um verschiedenen Gruppen verschiedene Seiten von dir zu zeigen.
-
-Du hast immer ein Profil, das als dein "Standard"- (default) oder "öffentliches" (public) Profil angelegt ist. 
-Dieses Profil ist immer für die Ã–ffentlichkeit zugänglich und kann nicht versteckt werden (hier mag es einige wenige Ausnahmen auf privaten oder getrennten Seiten geben). 
-Du kannst und solltest die Informationen, die du in deinem Ã¶ffentlichen Profil veröffentlichst, begrenzen.
-
-Das bedeutet, dass du folgende Informationen in dein Ã¶ffentlichen Profil eintragen solltest, wenn du willst, dass Freunde dich finden können ...
-
-* Dein richtiger Name
-* Ein Foto von **dir**
-* Dein geographischer Standort; zumindest das Land, in dem du lebst. 
-
-Ohne diese Basisinformationen kannst du hier sehr einsam sein. 
-Die meisten Leute, auch deine besten Freunde, werden nicht versuchen, einen Account mit Spitznamen und ohne Foto zu verbinden.
-
-Wenn du außerdem Leute mit gleichen Interessen treffen willst, dann nimm dir etwas Zeit und trage einige Stichworte ein. 
-Zum Beispiel etwas wie "Musik, Linux, Photographie" oder andere Dinge. 
-Du kannst so viele Stichworte eintragen, wie du willst.
-
-Dein "Standard-" oder "öffentliches" Profil wird außerdem Kontakten in anderen Netzwerken gezeigt, auch wenn sie nicht die Möglichkeit haben, die privaten Profile einzusehen. 
-Nur Mitglieder des Friendica-Netzwerks können alternative oder private Profile sehen.
-
-Um ein alternatives Profil zu erstellen, gehe auf "Profil verwalten/editieren". 
-Du kannst entweder ein bestehendes Profil bearbeiten, das Foto Ã¤ndern, oder ein neues Profil erstellen. 
-Du kannst ebenfalls einen Klon eines bestehenden Profils erstellen, falls du nur einige wenige Einstellungen Ã¤ndern, aber nicht alle Daten noch mal eingeben willst.
-
-Um bestimmten Personen ein Profil zuzuweisen, wähle die Person Ã¼ber "Kontakte" und klicke auf das Bearbeiten-Symbol (Stift). 
-Du wirst ein Auswahlmenü mit verschiedenen vorhandenen Profilen angezeigt bekommen. 
-Wenn diese Auswahl nicht angezeigt wird, dann ist die Person in einem nicht unterstützten Netzwerk und kann dadurch auch kein Profil zugewiesen bekommen.
-
-Wenn eine befreundete Person auf den "magischen Profillink" klickt, sieht sie das private Profil, das du dieser Person zugewiesen hast. 
-Wenn sie nicht eingeloggt ist oder das Profil von woanders angeschaut wird, wird nur das Ã¶ffentliche Profil angezeigt.
-
-Ein "magischer Profillink" erscheint, wenn man mit der Maus Ã¼ber den Kontaktnamen oder das Foto geht. 
-Der Cursor wird zur Hand und auf dem Bild erscheint ein Pfeil, der nach unten zeigt. 
-Dieser "magische Cursor" zeigt an, dass du ein spezielles Profil angezeigt bekommst, das nur für Freunde, aber nicht für die Ã–ffentlichkeit sichtbar ist.
-
-Du wirst außerdem möglicherweise entdecken (vorausgesetzt, du hast die nötigen Zugriffsrechte), dass du direkt auf die Seite einer anderen Person schreiben kannst (oft wird diese Beitragsart "wall-to-wall" genannt). 
-Ebenso kannst du die Möglichkeit haben, direkt Beiträge zu kommentieren, während du die Seite der anderen Person besuchst. 
-
-Es gibt zwei Einstellungen, welche erlauben, dein Profil ins Verzeichnis einzutragen, so dass du von anderen Personen gefunden werden kannst. 
-Du kannst diese Einstellungen auf deiner "Einstellungen"-Seite Ã¤ndern. 
-Die eine Einstellung erlaubt dir, dein Profil im Verzeichnis dieses Servers zu veröffentlichen. 
-Die zweite Option erlaubt es dir, dich in das globale Friendica-Verzeichnis einzutragen. 
-Dies ist ein riesiges Verzeichnis, dass alle Personen von vielen Friendica-Installationen weltweit umfasst.
-
-Wenn du für andere nicht sichtbar sein willst, dann kannst du dein Profil einfach unveröffentlicht lassen.
-
-Außerdem hast du möglicherweise mehrere Profile, aber nur ein Profilfoto. Dies ist beabsichtigt. 
-In frühen Tests haben wir mit verschiedenen Fotos für jedes Profil experimentiert und herausgefunden, dass es sehr verwirrend für die Nutzer ist. 
-Sie sehen möglicherweise je nach Profil, Seite oder Unterhaltung verschiedene Fotos und merken, dass es unterschiedliche Profile gibt, die sie nicht einsehen können.
-
-(Du kannst aber die Rich-Text-Infoboxen in deinem Profil nutzen und dort weitere Bilder in das Feld "Erzähle uns ein bisschen von dir â€¦" einfügen.)
-
-
-**Schlüsselwörter und Verzeichnissuche**
-
-Auf der Verzeichnisseite willst du vielleicht nach Personen deines Servers suchen, die ihre Profile veröffentlicht haben. 
-Die Suche richtet sich normalerweise nach deinem Spitznamen oder Teilen deines richtigen Namens. 
-Darüber hinaus wird dieses Feld auch andere Felder deines Profils wie Geschlecht, Ort, "über mich", Arbeit und Bildung finden.
-Du kannst zudem auch "Schlüsselwörter" in dein Standardprofil eintragen, so dass dich andere Personen Ã¼ber deine Interessen finden können. 
-Du hast zwei Schlüsselwortarten zur Auswahl - Ã¶ffentlich und privat. Private Schlüsselwörter werden *nicht* jedem angezeigt. 
-Du kannst diese Schlüsselwörter nutzen, um andere Personen zu finden, die ebenfalls in einer bestimmten Gruppe sind oder z.B. das Fischen mögen, ohne dass es jeder in einem Ã¶ffentlichen Profil sieht. 
-Öffentliche Schlüsselwörter werden auf der "Kontaktvorschläge"-Seite genutzt. 
-Auch wenn die Schlüsselwörter hier nicht direkt angezeigt werden, kann es trotzdem sein, dass diese im HTML-Code der Seite gesehen werden könnten.
-
-In der Verzeichnis-Suche kannst du ebenfalls die "booleasche"-Logik zu nutzen. Mit "+lesbisch +Florida" kannst du Leute finden, deren sexuelle Einstellung (oder andere Schlüsselwörter) das Wort "lesbisch" enthält und die in Florida leben. 
-Schau dir den Bereich Ã¼ber "Thematische Tags" auf der "[Tags und Erwähnungen-Seite](help/Tags-and-Mentions) für weitere Informationen, um booleansche Suchen durchzuführen.
-
-Auf deiner Kontaktseite ist der Link "Ähnliche Interessen", um damit andere Leute zu finden (falls dein Seitenadministrator das globale Verzeichnis nicht ausgeschaltet hat). 
-Hierfür werden die Schlüsselwörter aus deinen Ã¶ffentlichen und privaten Profilen genutzt, um Personen im globalen Verzeichnis zu finden, die gleiche oder Ã¤hnliche Schlüsselwörter haben (deine privaten Schlüsselwörter werden nicht in das globale Verzeichnis Ã¼bertragen oder gespeichert). 
-Je mehr Schlüsselwörter du einträgst, umso genauer ist die Suche. Das Suchergebnis ist nach Relevanz sortiert. 
-Gegebenenfalls stehst du ganz oben auf der Liste - schließlich bist du die Person, die am besten zu deinen Schlüsselwörtern passt.
index 43659db079a6fe974276716d45ba3c76464b9c75..a69bd01b4971edfcea66cb166a3542111c3cd931 100644 (file)
@@ -23,6 +23,7 @@ use Friendica\Model\Contact;
 use Friendica\Model\Group;
 use Friendica\Model\Item;
 use Friendica\Model\Mail;
+use Friendica\Model\Notify;
 use Friendica\Model\Photo;
 use Friendica\Model\Profile;
 use Friendica\Model\User;
@@ -5906,19 +5907,25 @@ function api_friendica_notification($type)
        if ($a->argc!==3) {
                throw new BadRequestException("Invalid argument count");
        }
-       $notes = DI::notify()->getAll([], ['seen' => 'ASC', 'date' => 'DESC'], 50);
+
+       $notifications = DI::notify()->select(['uid' => api_user()], ['order' => ['seen' => 'ASC', 'date' => 'DESC'], 'limit' => 50]);
 
        if ($type == "xml") {
-               $xmlnotes = [];
-               if (!empty($notes)) {
-                       foreach ($notes as $note) {
-                               $xmlnotes[] = ["@attributes" => $note];
+               $xmlnotes = false;
+               if (!empty($notifications)) {
+                       foreach ($notifications as $notification) {
+                               $xmlnotes[] = ["@attributes" => $notification->toArray()];
                        }
                }
 
-               $notes = $xmlnotes;
+               $result = $xmlnotes;
+       } elseif (count($notifications) > 0) {
+               $result = $notifications->getArrayCopy();
+       } else {
+               $result = false;
        }
-       return api_format_data("notes", $type, ['note' => $notes]);
+
+       return api_format_data("notes", $type, ['note' => $result]);
 }
 
 /**
@@ -5936,37 +5943,36 @@ function api_friendica_notification($type)
  */
 function api_friendica_notification_seen($type)
 {
-       $a = DI::app();
+       $a         = DI::app();
        $user_info = api_get_user($a);
 
        if (api_user() === false || $user_info === false) {
                throw new ForbiddenException();
        }
-       if ($a->argc!==4) {
+       if ($a->argc !== 4) {
                throw new BadRequestException("Invalid argument count");
        }
 
        $id = (!empty($_REQUEST['id']) ? intval($_REQUEST['id']) : 0);
 
-       $nm = DI::notify();
-       $note = $nm->getByID($id);
-       if (is_null($note)) {
-               throw new BadRequestException("Invalid argument");
-       }
-
-       $nm->setSeen($note);
-       if ($note['otype']=='item') {
-               // would be really better with an ItemsManager and $im->getByID() :-P
-               $item = Item::selectFirstForUser(api_user(), [], ['id' => $note['iid'], 'uid' => api_user()]);
-               if (DBA::isResult($item)) {
-                       // we found the item, return it to the user
-                       $ret = api_format_items([$item], $user_info, false, $type);
-                       $data = ['status' => $ret];
-                       return api_format_data("status", $type, $data);
+       try {
+               $notification = DI::notify()->getByID($id);
+               $notification->setSeen();
+
+               if ($notification->otype === Notify::OTYPE_ITEM) {
+                       $item = Item::selectFirstForUser(api_user(), [], ['id' => $notification->iid, 'uid' => api_user()]);
+                       if (DBA::isResult($item)) {
+                               // we found the item, return it to the user
+                               $ret  = api_format_items([$item], $user_info, false, $type);
+                               $data = ['status' => $ret];
+                               return api_format_data("status", $type, $data);
+                       }
+                       // the item can't be found, but we set the notification as seen, so we count this as a success
                }
-               // the item can't be found, but we set the note as seen, so we count this as a success
+               return api_format_data('result', $type, ['result' => "success"]);
+       } catch (NotFoundException $e) {
+               throw new BadRequestException('Invalid argument');
        }
-       return api_format_data('result', $type, ['result' => "success"]);
 }
 
 /// @TODO move to top of file or somewhere better
index ed273a52ce22c70985df1b77c6bfeb1b2f372b1a..3f500717aa14e6959dfad8ba47995e41cdd97b7b 100644 (file)
@@ -791,7 +791,7 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
 /**
  * Fetch all comments from a query. Additionally set the newest resharer as thread owner.
  *
- * @param array   $thread_items Database statement with thread posts
+ * @param mixed   $thread_items Database statement with thread posts
  * @param boolean $pinned       Is the item pinned?
  *
  * @return array items with parents and comments
index 4bd9eb6967e1a51fcb476e386f0ae185bc951ef0..3332f4a082ec75605e5888b4a201543393700f48 100644 (file)
@@ -12,11 +12,11 @@ use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Model\Item;
 use Friendica\Model\ItemContent;
+use Friendica\Model\Notify;
 use Friendica\Model\User;
 use Friendica\Model\UserItem;
+use Friendica\Object\Email;
 use Friendica\Protocol\Activity;
-use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Emailer;
 
 /**
  * Creates a notification entry and possibly sends a mail
@@ -160,7 +160,7 @@ function notification($params)
 
                // if it's a post figure out who's post it is.
                $item = null;
-               if ($params['otype'] === 'item' && $parent_id) {
+               if ($params['otype'] === Notify::OTYPE_ITEM && $parent_id) {
                        $item = Item::selectFirstForUser($params['uid'], Item::ITEM_FIELDLIST, ['id' => $parent_id, 'deleted' => false]);
                }
 
@@ -482,47 +482,25 @@ function notification($params)
        $notify_id = 0;
 
        if ($show_in_notification_page) {
-               Logger::log("adding notification entry", Logger::DEBUG);
-
-               /// @TODO One statement is enough
-               $datarray = [];
-               $datarray['name']  = $params['source_name'];
-               $datarray['name_cache'] = strip_tags(BBCode::convert($params['source_name']));
-               $datarray['url']   = $params['source_link'];
-               $datarray['photo'] = $params['source_photo'];
-               $datarray['date']  = DateTimeFormat::utcNow();
-               $datarray['uid']   = $params['uid'];
-               $datarray['link']  = $itemlink;
-               $datarray['iid']   = $item_id;
-               $datarray['parent'] = $parent_id;
-               $datarray['type']  = $params['type'];
-               $datarray['verb']  = $params['verb'];
-               $datarray['otype'] = $params['otype'];
-               $datarray['abort'] = false;
-
-               Hook::callAll('enotify_store', $datarray);
-
-               if ($datarray['abort']) {
-                       return false;
-               }
-
-               // create notification entry in DB
-               $fields = ['name' => $datarray['name'], 'url' => $datarray['url'],
-                       'photo' => $datarray['photo'], 'date' => $datarray['date'], 'uid' => $datarray['uid'],
-                       'link' => $datarray['link'], 'iid' => $datarray['iid'], 'parent' => $datarray['parent'],
-                       'type' => $datarray['type'], 'verb' => $datarray['verb'], 'otype' => $datarray['otype'],
-                       'name_cache' => $datarray["name_cache"]];
-               DBA::insert('notify', $fields);
+               $notification = DI::notify()->insert([
+                       'name'   => $params['source_name'],
+                       'url'    => $params['source_link'],
+                       'photo'  => $params['source_photo'],
+                       'uid'    => $params['uid'],
+                       'iid'    => $item_id,
+                       'parent' => $parent_id,
+                       'type'   => $params['type'],
+                       'verb'   => $params['verb'],
+                       'otype'  => $params['otype'],
+               ]);
 
-               $notify_id = DBA::lastInsertId();
+               $notification->link = DI::baseUrl() . '/notification/view/' . $notification->id;
+               $notification->msg  = Renderer::replaceMacros($epreamble, ['$itemlink' => $notification->link]);
 
-               $itemlink = DI::baseUrl().'/notify/view/'.$notify_id;
-               $msg = Renderer::replaceMacros($epreamble, ['$itemlink' => $itemlink]);
-               $msg_cache = format_notification_message($datarray['name_cache'], strip_tags(BBCode::convert($msg)));
+               DI::notify()->update($notification);
 
-               $fields = ['msg' => $msg, 'msg_cache' => $msg_cache];
-               $condition = ['id' => $notify_id, 'uid' => $params['uid']];
-               DBA::update('notify', $fields, $condition);
+               $itemlink  = $notification->link;
+               $notify_id = $notification->id;
        }
 
        // send email notification if notification preferences permit
@@ -533,19 +511,19 @@ function notification($params)
                Logger::log('sending notification email');
 
                if (isset($params['parent']) && (intval($params['parent']) != 0)) {
-                       $id_for_parent = $params['parent']."@".$hostname;
+                       $id_for_parent = $params['parent'] . "@" . $hostname;
 
                        // Is this the first email notification for this parent item and user?
                        if (!DBA::exists('notify-threads', ['master-parent-item' => $params['parent'], 'receiver-uid' => $params['uid']])) {
-                               Logger::log("notify_id:".intval($notify_id).", parent: ".intval($params['parent'])."uid: ".intval($params['uid']), Logger::DEBUG);
+                               Logger::log("notify_id:" . intval($notify_id) . ", parent: " . intval($params['parent']) . "uid: " . intval($params['uid']), Logger::DEBUG);
 
-                               $fields = ['notify-id' => $notify_id, 'master-parent-item' => $params['parent'],
-                                       'receiver-uid' => $params['uid'], 'parent-item' => 0];
+                               $fields = ['notify-id'    => $notify_id, 'master-parent-item' => $params['parent'],
+                                          'receiver-uid' => $params['uid'], 'parent-item' => 0];
                                DBA::insert('notify-threads', $fields);
 
                                $additional_mail_header .= "Message-ID: <${id_for_parent}>\n";
-                               $log_msg = "include/enotify: No previous notification found for this parent:\n".
-                                               "  parent: ${params['parent']}\n"."  uid   : ${params['uid']}\n";
+                               $log_msg                = "include/enotify: No previous notification found for this parent:\n" .
+                                                         "  parent: ${params['parent']}\n" . "  uid   : ${params['uid']}\n";
                                Logger::log($log_msg, Logger::DEBUG);
                        } else {
                                // If not, just "follow" the thread.
@@ -557,30 +535,30 @@ function notification($params)
                $textversion = BBCode::toPlaintext($body);
                $htmlversion = BBCode::convert($body);
 
-               $datarray = [];
-               $datarray['banner'] = $banner;
-               $datarray['product'] = $product;
-               $datarray['preamble'] = $preamble;
-               $datarray['sitename'] = $sitename;
-               $datarray['siteurl'] = $siteurl;
-               $datarray['type'] = $params['type'];
-               $datarray['parent'] = $parent_id;
-               $datarray['source_name'] = $params['source_name'] ?? '';
-               $datarray['source_link'] = $params['source_link'] ?? '';
+               $datarray                 = [];
+               $datarray['banner']       = $banner;
+               $datarray['product']      = $product;
+               $datarray['preamble']     = $preamble;
+               $datarray['sitename']     = $sitename;
+               $datarray['siteurl']      = $siteurl;
+               $datarray['type']         = $params['type'];
+               $datarray['parent']       = $parent_id;
+               $datarray['source_name']  = $params['source_name'] ?? '';
+               $datarray['source_link']  = $params['source_link'] ?? '';
                $datarray['source_photo'] = $params['source_photo'] ?? '';
-               $datarray['uid'] = $params['uid'];
-               $datarray['username'] = $params['to_name'] ?? '';
-               $datarray['hsitelink'] = $hsitelink;
-               $datarray['tsitelink'] = $tsitelink;
-               $datarray['hitemlink'] = '<a href="'.$itemlink.'">'.$itemlink.'</a>';
-               $datarray['titemlink'] = $itemlink;
-               $datarray['thanks'] = $thanks;
-               $datarray['site_admin'] = $site_admin;
-               $datarray['title'] = stripslashes($title);
-               $datarray['htmlversion'] = $htmlversion;
-               $datarray['textversion'] = $textversion;
-               $datarray['subject'] = $subject;
-               $datarray['headers'] = $additional_mail_header;
+               $datarray['uid']          = $params['uid'];
+               $datarray['username']     = $params['to_name'] ?? '';
+               $datarray['hsitelink']    = $hsitelink;
+               $datarray['tsitelink']    = $tsitelink;
+               $datarray['hitemlink']    = '<a href="' . $itemlink . '">' . $itemlink . '</a>';
+               $datarray['titemlink']    = $itemlink;
+               $datarray['thanks']       = $thanks;
+               $datarray['site_admin']   = $site_admin;
+               $datarray['title']        = stripslashes($title);
+               $datarray['htmlversion']  = $htmlversion;
+               $datarray['textversion']  = $textversion;
+               $datarray['subject']      = $subject;
+               $datarray['headers']      = $additional_mail_header;
 
                Hook::callAll('enotify_mail', $datarray);
 
@@ -589,59 +567,53 @@ function notification($params)
                $content_allowed = ((!DI::config()->get('system', 'enotify_no_content')) || ($params['type'] == SYSTEM_EMAIL));
 
                // load the template for private message notifications
-               $tpl = Renderer::getMarkupTemplate('email_notify_html.tpl');
+               $tpl             = Renderer::getMarkupTemplate('email_notify_html.tpl');
                $email_html_body = Renderer::replaceMacros($tpl, [
-                       '$banner'       => $datarray['banner'],
-                       '$product'      => $datarray['product'],
-                       '$preamble'     => str_replace("\n", "<br>\n", $datarray['preamble']),
-                       '$sitename'     => $datarray['sitename'],
-                       '$siteurl'      => $datarray['siteurl'],
-                       '$source_name'  => $datarray['source_name'],
-                       '$source_link'  => $datarray['source_link'],
-                       '$source_photo' => $datarray['source_photo'],
-                       '$username'     => $datarray['username'],
-                       '$hsitelink'    => $datarray['hsitelink'],
-                       '$hitemlink'    => $datarray['hitemlink'],
-                       '$thanks'       => $datarray['thanks'],
-                       '$site_admin'   => $datarray['site_admin'],
-                       '$title'        => $datarray['title'],
-                       '$htmlversion'  => $datarray['htmlversion'],
-                       '$content_allowed'      => $content_allowed,
+                       '$banner'          => $datarray['banner'],
+                       '$product'         => $datarray['product'],
+                       '$preamble'        => str_replace("\n", "<br>\n", $datarray['preamble']),
+                       '$sitename'        => $datarray['sitename'],
+                       '$siteurl'         => $datarray['siteurl'],
+                       '$source_name'     => $datarray['source_name'],
+                       '$source_link'     => $datarray['source_link'],
+                       '$source_photo'    => $datarray['source_photo'],
+                       '$username'        => $datarray['username'],
+                       '$hsitelink'       => $datarray['hsitelink'],
+                       '$hitemlink'       => $datarray['hitemlink'],
+                       '$thanks'          => $datarray['thanks'],
+                       '$site_admin'      => $datarray['site_admin'],
+                       '$title'           => $datarray['title'],
+                       '$htmlversion'     => $datarray['htmlversion'],
+                       '$content_allowed' => $content_allowed,
                ]);
 
                // load the template for private message notifications
-               $tpl = Renderer::getMarkupTemplate('email_notify_text.tpl');
+               $tpl             = Renderer::getMarkupTemplate('email_notify_text.tpl');
                $email_text_body = Renderer::replaceMacros($tpl, [
-                       '$banner'       => $datarray['banner'],
-                       '$product'      => $datarray['product'],
-                       '$preamble'     => $datarray['preamble'],
-                       '$sitename'     => $datarray['sitename'],
-                       '$siteurl'      => $datarray['siteurl'],
-                       '$source_name'  => $datarray['source_name'],
-                       '$source_link'  => $datarray['source_link'],
-                       '$source_photo' => $datarray['source_photo'],
-                       '$username'     => $datarray['username'],
-                       '$tsitelink'    => $datarray['tsitelink'],
-                       '$titemlink'    => $datarray['titemlink'],
-                       '$thanks'       => $datarray['thanks'],
-                       '$site_admin'   => $datarray['site_admin'],
-                       '$title'        => $datarray['title'],
-                       '$textversion'  => $datarray['textversion'],
-                       '$content_allowed'      => $content_allowed,
+                       '$banner'          => $datarray['banner'],
+                       '$product'         => $datarray['product'],
+                       '$preamble'        => $datarray['preamble'],
+                       '$sitename'        => $datarray['sitename'],
+                       '$siteurl'         => $datarray['siteurl'],
+                       '$source_name'     => $datarray['source_name'],
+                       '$source_link'     => $datarray['source_link'],
+                       '$source_photo'    => $datarray['source_photo'],
+                       '$username'        => $datarray['username'],
+                       '$tsitelink'       => $datarray['tsitelink'],
+                       '$titemlink'       => $datarray['titemlink'],
+                       '$thanks'          => $datarray['thanks'],
+                       '$site_admin'      => $datarray['site_admin'],
+                       '$title'           => $datarray['title'],
+                       '$textversion'     => $datarray['textversion'],
+                       '$content_allowed' => $content_allowed,
                ]);
 
+               $email = new Email($sender_name, $sender_email, $sender_email, $params['to_email'],
+                       $datarray['subject'], $email_html_body, $email_text_body,
+                       $datarray['headers'], $params['uid']);
+
                // use the Emailer class to send the message
-               return Emailer::send([
-                       'uid' => $params['uid'],
-                       'fromName' => $sender_name,
-                       'fromEmail' => $sender_email,
-                       'replyTo' => $sender_email,
-                       'toEmail' => $params['to_email'],
-                       'messageSubject' => $datarray['subject'],
-                       'htmlVersion' => $email_html_body,
-                       'textVersion' => $email_text_body,
-                       'additionalMailHeader' => $datarray['headers']
-               ]);
+               return DI::emailer()->send($email);
        }
 
        return false;
@@ -732,27 +704,3 @@ function check_item_notification($itemid, $uid, $notification_type) {
 
        notification($params);
 }
-
-/**
- * Formats a notification message with the notification author
- *
- * Replace the name with {0} but ensure to make that only once. The {0} is used
- * later and prints the name in bold.
- *
- * @param string $name
- * @param string $message
- * @return string Formatted message
- */
-function format_notification_message($name, $message) {
-       if ($name != '') {
-               $pos = strpos($message, $name);
-       } else {
-               $pos = false;
-       }
-
-       if ($pos !== false) {
-               $message = substr_replace($message, '{0}', $pos, strlen($name));
-       }
-
-       return $message;
-}
index e6570018b7cb64aa8fcc972c5ff6b21b3992a2df..9e32b87d6f60bc829eb8a9c7c3936b3c855ddc4b 100644 (file)
@@ -19,6 +19,7 @@ use Friendica\Model\Contact;
 use Friendica\Model\Event;
 use Friendica\Model\Item;
 use Friendica\Model\Profile;
+use Friendica\Module\BaseProfile;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Temporal;
 
@@ -121,7 +122,7 @@ function cal_content(App $a)
        $sql_extra = " AND `event`.`cid` = 0 " . $sql_perms;
 
        // get the tab navigation bar
-       $tabs = Profile::getTabs($a, 'cal', false, $a->data['user']['nickname']);
+       $tabs = BaseProfile::getTabsHTML($a, 'cal', false, $a->data['user']['nickname']);
 
        // The view mode part is similiar to /mod/events.php
        if ($mode == 'view') {
index 9ec7e05cae7c11728b9b9565e6833b1b7ad1f15f..582bcde28e040f0bfddf49f2c8ca4c6f5b09d1bd 100644 (file)
@@ -102,7 +102,7 @@ function display_init(App $a)
                if (!empty($a->user['nickname']) && $nickname != $a->user['nickname']) {
                        $profile = DBA::fetchFirst("SELECT `profile`.* , `contact`.`avatar-date` AS picdate, `user`.* FROM `profile`
                                INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
-                               WHERE `user`.`nickname` = ? AND `profile`.`is-default` AND `contact`.`self` LIMIT 1",
+                               WHERE `user`.`nickname` = ? AND `contact`.`self` LIMIT 1",
                                $nickname
                        );
                        if (DBA::isResult($profile)) {
index 5601c4449a86291d08ffb04349c3e70a623235ff..ffe67f67fededc099898f0157159120936157d80 100644 (file)
@@ -16,8 +16,8 @@ use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Model\Event;
 use Friendica\Model\Item;
-use Friendica\Model\Profile;
 use Friendica\Model\User;
+use Friendica\Module\BaseProfile;
 use Friendica\Module\Security\Login;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Strings;
@@ -251,7 +251,7 @@ function events_content(App $a)
        $tabs = '';
        // tabs
        if ($a->theme_events_in_profile) {
-               $tabs = Profile::getTabs($a, 'events', true);
+               $tabs = BaseProfile::getTabsHTML($a, 'events', true);
        }
 
        $mode = 'view';
index a9c5d43580794d660e7fa2a83099c994bd36c6a4..8b795d28cbecdb938060d4c033fdf95a81c35da3 100644 (file)
@@ -18,7 +18,6 @@
 use Friendica\App;
 use Friendica\Content\Pager;
 use Friendica\Content\Text\BBCode;
-use Friendica\Content\Text\HTML;
 use Friendica\Core\Hook;
 use Friendica\Core\Logger;
 use Friendica\Core\Protocol;
@@ -34,11 +33,10 @@ use Friendica\Model\FileTag;
 use Friendica\Model\Item;
 use Friendica\Model\Photo;
 use Friendica\Model\Term;
+use Friendica\Object\EMail\ItemCCEMail;
 use Friendica\Protocol\Activity;
 use Friendica\Protocol\Diaspora;
-use Friendica\Protocol\Email;
 use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Emailer;
 use Friendica\Util\Security;
 use Friendica\Util\Strings;
 use Friendica\Worker\Delivery;
@@ -788,35 +786,15 @@ function item_post(App $a) {
        Hook::callAll('post_local_end', $datarray);
 
        if (strlen($emailcc) && $profile_uid == local_user()) {
-               $erecips = explode(',', $emailcc);
-               if (count($erecips)) {
-                       foreach ($erecips as $recip) {
-                               $addr = trim($recip);
-                               if (!strlen($addr)) {
+               $recipients = explode(',', $emailcc);
+               if (count($recipients)) {
+                       foreach ($recipients as $recipient) {
+                               $address = trim($recipient);
+                               if (!strlen($address)) {
                                        continue;
                                }
-                               $disclaimer = '<hr />' . DI::l10n()->t('This message was sent to you by %s, a member of the Friendica social network.', $a->user['username'])
-                                       . '<br />';
-                               $disclaimer .= DI::l10n()->t('You may visit them online at %s', DI::baseUrl() . '/profile/' . $a->user['nickname']) . EOL;
-                               $disclaimer .= DI::l10n()->t('Please contact the sender by replying to this post if you do not wish to receive these messages.') . EOL;
-                               if (!$datarray['title']=='') {
-                                       $subject = Email::encodeHeader($datarray['title'], 'UTF-8');
-                               } else {
-                                       $subject = Email::encodeHeader('[Friendica]' . ' ' . DI::l10n()->t('%s posted an update.', $a->user['username']), 'UTF-8');
-                               }
-                               $link = '<a href="' . DI::baseUrl() . '/profile/' . $a->user['nickname'] . '"><img src="' . $author['thumb'] . '" alt="' . $a->user['username'] . '" /></a><br /><br />';
-                               $html    = Item::prepareBody($datarray);
-                               $message = '<html><body>' . $link . $html . $disclaimer . '</body></html>';
-                               $params =  [
-                                       'fromName' => $a->user['username'],
-                                       'fromEmail' => $a->user['email'],
-                                       'toEmail' => $addr,
-                                       'replyTo' => $a->user['email'],
-                                       'messageSubject' => $subject,
-                                       'htmlVersion' => $message,
-                                       'textVersion' => HTML::toPlaintext($html.$disclaimer)
-                               ];
-                               Emailer::send($params);
+                               DI::emailer()->send(new ItemCCEMail(DI::app(), DI::l10n(), DI::baseUrl(),
+                                       $datarray, $address, $author['thumb'] ?? ''));
                        }
                }
        }
index 67b8ea6fd59e63760fad9ae02238abc0e0aa82c5..95847760023d29f989f03f3afab0b246d445a2c5 100644 (file)
@@ -26,8 +26,7 @@ function msearch_post(App $a)
                "SELECT COUNT(*) AS `total`
                        FROM `profile`
                        JOIN `user` ON `user`.`uid` = `profile`.`uid`
-                       WHERE `is-default` = 1
-                       AND `user`.`hidewall` = 0
+                       WHERE `user`.`hidewall` = 0
                        AND MATCH(`pub_keywords`) AGAINST (?)",
                $search
        );
@@ -42,8 +41,7 @@ function msearch_post(App $a)
                "SELECT `pub_keywords`, `username`, `nickname`, `user`.`uid`
                        FROM `user`
                        JOIN `profile` ON `user`.`uid` = `profile`.`uid`
-                       WHERE `is-default` = 1
-                       AND `user`.`hidewall` = 0
+                       WHERE `user`.`hidewall` = 0
                        AND MATCH(`pub_keywords`) AGAINST (?)
                        LIMIT ?, ?",
                $search,
index db6d8eaf4516f48f8e8f84dc60c33c1e30b1ca49..1bbddf2196c19a04319150166b5a46b28c0fa616 100644 (file)
@@ -879,7 +879,7 @@ function network_tabs(App $a)
 {
        // item filter tabs
        /// @TODO fix this logic, reduce duplication
-       /// $a->page['content'] .= '<div class="tabs-wrapper">';
+       /// DI::page()['content'] .= '<div class="tabs-wrapper">';
        list($no_active, $all_active, $post_active, $conv_active, $new_active, $starred_active, $bookmarked_active) = network_query_get_sel_tab($a);
 
        // if no tabs are selected, defaults to activitys
index 536029338f815f174969a696fdfc0d59c60976b8..38a72a741fd7e4ba2c3a0bfe62ab22034687fa79 100644 (file)
@@ -9,7 +9,7 @@ use Friendica\Content\Pager;
 use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Model\Item;
-use Friendica\Model\Profile;
+use Friendica\Module\BaseProfile;
 
 function notes_init(App $a)
 {
@@ -28,7 +28,7 @@ function notes_content(App $a, $update = false)
                return;
        }
 
-       $o = Profile::getTabs($a, 'notes', true);
+       $o = BaseProfile::getTabsHTML($a, 'notes', true);
 
        if (!$update) {
                $o .= '<h3>' . DI::l10n()->t('Personal Notes') . '</h3>';
diff --git a/mod/notifications.php b/mod/notifications.php
deleted file mode 100644 (file)
index deee5f1..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-<?php
-/**
- * @file mod/notifications.php
- * The notifications module
- */
-
-use Friendica\App;
-use Friendica\Content\ContactSelector;
-use Friendica\Content\Nav;
-use Friendica\Content\Pager;
-use Friendica\Core\Protocol;
-use Friendica\Core\Renderer;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Model\Notify;
-use Friendica\Module\Security\Login;
-
-/** @var array Array of URL parameters */
-const URL_TYPES = [
-       Notify::NETWORK  => 'network',
-       Notify::SYSTEM   => 'system',
-       Notify::HOME     => 'home',
-       Notify::PERSONAL => 'personal',
-       Notify::INTRO    => 'intros',
-];
-
-/** @var array Array of the allowed notifies and their printable name */
-const PRINT_TYPES = [
-       Notify::NETWORK  => 'Network',
-       Notify::SYSTEM   => 'System',
-       Notify::HOME     => 'Home',
-       Notify::PERSONAL => 'Personal',
-       Notify::INTRO    => 'Introductions',
-];
-
-/** @var array The array of access keys for notify pages */
-const ACCESS_KEYS = [
-       Notify::NETWORK  => 'w',
-       Notify::SYSTEM   => 'y',
-       Notify::HOME     => 'h',
-       Notify::PERSONAL => 'r',
-       Notify::INTRO    => 'i',
-];
-
-function notifications_post(App $a)
-{
-       if (!local_user()) {
-               DI::baseUrl()->redirect();
-       }
-
-       $request_id = (($a->argc > 1) ? $a->argv[1] : 0);
-
-       if ($request_id === 'all') {
-               return;
-       }
-
-       if ($request_id) {
-               $intro = DI::intro()->selectFirst(['id' => $request_id, 'uid' => local_user()]);
-
-               switch ($_POST['submit']) {
-                       case DI::l10n()->t('Discard'):
-                               $intro->discard();
-                               break;
-                       case DI::l10n()->t('Ignore'):
-                               $intro->ignore();
-                               break;
-               }
-
-               DI::baseUrl()->redirect('notifications/intros');
-       }
-}
-
-function notifications_content(App $a)
-{
-       if (!local_user()) {
-               notice(DI::l10n()->t('Permission denied.') . EOL);
-               return Login::form();
-       }
-
-       $page = ($_REQUEST['page'] ?? 0) ?: 1;
-       $show = ($_REQUEST['show'] ?? '') === 'all';
-
-       Nav::setSelected('notifications');
-
-       $json = (($a->argc > 1 && $a->argv[$a->argc - 1] === 'json') ? true : false);
-
-       $nm = DI::notify();
-
-       $o = '';
-       // Get the nav tabs for the notification pages
-       $tabs = getTabs(DI::args()->get(1, ''));
-       $notif_content = [];
-       $notif_nocontent = '';
-
-       // Notification results per page
-       $perpage = 20;
-       $startrec = ($page * $perpage) - $perpage;
-
-       $notif_header = DI::l10n()->t('Notifications');
-
-       $all = false;
-
-       // Get introductions
-       if ((($a->argc > 1) && ($a->argv[1] == 'intros')) || (($a->argc == 1))) {
-               Nav::setSelected('introductions');
-
-               $id = 0;
-               if (!empty($a->argv[2]) && intval($a->argv[2]) != 0) {
-                       $id = (int)$a->argv[2];
-               }
-
-               $all = (($a->argc > 2) && ($a->argv[2] == 'all'));
-
-               $notifs = $nm->getIntroList($all, $startrec, $perpage, $id);
-
-       // Get the network notifications
-       } elseif (($a->argc > 1) && ($a->argv[1] == 'network')) {
-               $notif_header = DI::l10n()->t('Network Notifications');
-               $notifs = $nm->getNetworkList($show, $startrec, $perpage);
-
-       // Get the system notifications
-       } elseif (($a->argc > 1) && ($a->argv[1] == 'system')) {
-               $notif_header = DI::l10n()->t('System Notifications');
-               $notifs = $nm->getSystemList($show, $startrec, $perpage);
-
-       // Get the personal notifications
-       } elseif (($a->argc > 1) && ($a->argv[1] == 'personal')) {
-               $notif_header = DI::l10n()->t('Personal Notifications');
-               $notifs = $nm->getPersonalList($show, $startrec, $perpage);
-
-       // Get the home notifications
-       } elseif (($a->argc > 1) && ($a->argv[1] == 'home')) {
-               $notif_header = DI::l10n()->t('Home Notifications');
-               $notifs = $nm->getHomeList($show, $startrec, $perpage);
-       // fallback - redirect to main page
-       } else {
-               DI::baseUrl()->redirect('notifications');
-       }
-
-       // Set the pager
-       $pager = new Pager(DI::args()->getQueryString(), $perpage);
-
-       // Add additional informations (needed for json output)
-       $notifs['items_page'] = $pager->getItemsPerPage();
-       $notifs['page'] = $pager->getPage();
-
-       // Json output
-       if (intval($json) === 1) {
-               System::jsonExit($notifs);
-       }
-
-       $notif_tpl = Renderer::getMarkupTemplate('notifications.tpl');
-
-       $notif_show_lnk = [
-               'href' => ($show ? 'notifications/' . $notifs['ident'] : 'notifications/' . $notifs['ident'] . '?show=all' ),
-               'text' => ($show ? DI::l10n()->t('Show unread') : DI::l10n()->t('Show all')),
-       ];
-
-       // Process the data for template creation
-       if (($notifs['ident'] ?? '') == 'introductions') {
-               $sugg = Renderer::getMarkupTemplate('suggestions.tpl');
-               $tpl = Renderer::getMarkupTemplate('intros.tpl');
-
-               // The link to switch between ignored and normal connection requests
-               $notif_show_lnk = [
-                       'href' => (!$all ? 'notifications/intros/all' : 'notifications/intros' ),
-                       'text' => (!$all ? DI::l10n()->t('Show Ignored Requests') : DI::l10n()->t('Hide Ignored Requests'))
-               ];
-
-               // Loop through all introduction notifications.This creates an array with the output html for each
-               // introduction
-               foreach ($notifs['notifications'] as $notif) {
-
-                       // There are two kind of introduction. Contacts suggested by other contacts and normal connection requests.
-                       // We have to distinguish between these two because they use different data.
-                       switch ($notif['label']) {
-                               case 'friend_suggestion':
-                                       $notif_content[] = Renderer::replaceMacros($sugg, [
-                                               '$type'       => $notif['label'],
-                                               '$str_notifytype' => DI::l10n()->t('Notification type:'),
-                                               '$notify_type'=> $notif['notify_type'],
-                                               '$intro_id'   => $notif['intro_id'],
-                                               '$lbl_madeby' => DI::l10n()->t('Suggested by:'),
-                                               '$madeby'     => $notif['madeby'],
-                                               '$madeby_url' => $notif['madeby_url'],
-                                               '$madeby_zrl' => $notif['madeby_zrl'],
-                                               '$madeby_addr'=> $notif['madeby_addr'],
-                                               '$contact_id' => $notif['contact_id'],
-                                               '$photo'      => $notif['photo'],
-                                               '$fullname'   => $notif['name'],
-                                               '$url'        => $notif['url'],
-                                               '$zrl'        => $notif['zrl'],
-                                               '$lbl_url'    => DI::l10n()->t('Profile URL'),
-                                               '$addr'       => $notif['addr'],
-                                               '$hidden'     => ['hidden', DI::l10n()->t('Hide this contact from others'), ($notif['hidden'] == 1), ''],
-                                               '$knowyou'    => $notif['knowyou'],
-                                               '$approve'    => DI::l10n()->t('Approve'),
-                                               '$note'       => $notif['note'],
-                                               '$request'    => $notif['request'],
-                                               '$ignore'     => DI::l10n()->t('Ignore'),
-                                               '$discard'    => DI::l10n()->t('Discard'),
-                                       ]);
-                                       break;
-
-                               // Normal connection requests
-                               default:
-                                       $friend_selected = (($notif['network'] !== Protocol::OSTATUS) ? ' checked="checked" ' : ' disabled ');
-                                       $fan_selected = (($notif['network'] === Protocol::OSTATUS) ? ' checked="checked" disabled ' : '');
-
-                                       $lbl_knowyou = '';
-                                       $knowyou     = '';
-                                       $helptext    = '';
-                                       $helptext2   = '';
-                                       $helptext3   = '';
-
-                                       if ($notif['network'] === Protocol::DFRN) {
-                                               $lbl_knowyou = DI::l10n()->t('Claims to be known to you: ');
-                                               $knowyou   = (($notif['knowyou']) ? DI::l10n()->t('yes') : DI::l10n()->t('no'));
-                                               $helptext  = DI::l10n()->t('Shall your connection be bidirectional or not?');
-                                               $helptext2 = DI::l10n()->t('Accepting %s as a friend allows %s to subscribe to your posts, and you will also receive updates from them in your news feed.', $notif['name'], $notif['name']);
-                                               $helptext3 = DI::l10n()->t('Accepting %s as a subscriber allows them to subscribe to your posts, but you will not receive updates from them in your news feed.', $notif['name']);
-                                       } elseif ($notif['network'] === Protocol::DIASPORA) {
-                                               $helptext  = DI::l10n()->t('Shall your connection be bidirectional or not?');
-                                               $helptext2 = DI::l10n()->t('Accepting %s as a friend allows %s to subscribe to your posts, and you will also receive updates from them in your news feed.', $notif['name'], $notif['name']);
-                                               $helptext3 = DI::l10n()->t('Accepting %s as a sharer allows them to subscribe to your posts, but you will not receive updates from them in your news feed.', $notif['name']);
-                                       }
-
-                                       $dfrn_tpl = Renderer::getMarkupTemplate('netfriend.tpl');
-                                       $dfrn_text = Renderer::replaceMacros($dfrn_tpl, [
-                                               '$intro_id'    => $notif['intro_id'],
-                                               '$friend_selected' => $friend_selected,
-                                               '$fan_selected'=> $fan_selected,
-                                               '$approve_as1' => $helptext,
-                                               '$approve_as2' => $helptext2,
-                                               '$approve_as3' => $helptext3,
-                                               '$as_friend'   => DI::l10n()->t('Friend'),
-                                               '$as_fan'      => (($notif['network'] == Protocol::DIASPORA) ? DI::l10n()->t('Sharer') : DI::l10n()->t('Subscriber'))
-                                       ]);
-
-                                       $contact = DBA::selectFirst('contact', ['network', 'protocol'], ['id' => $notif['contact_id']]);
-
-                                       if (($contact['network'] != Protocol::DFRN) || ($contact['protocol'] == Protocol::ACTIVITYPUB)) {
-                                               $action = 'follow_confirm';
-                                       } else {
-                                               $action = 'dfrn_confirm';
-                                       }
-
-                                       $header = $notif['name'];
-
-                                       if ($notif['addr'] != '') {
-                                               $header .= ' <' . $notif['addr'] . '>';
-                                       }
-
-                                       $header .= ' (' . ContactSelector::networkToName($notif['network'], $notif['url']) . ')';
-
-                                       if ($notif['network'] != Protocol::DIASPORA) {
-                                               $discard = DI::l10n()->t('Discard');
-                                       } else {
-                                               $discard = '';
-                                       }
-
-                                       $notif_content[] = Renderer::replaceMacros($tpl, [
-                                               '$type'        => $notif['label'],
-                                               '$header'      => $header,
-                                               '$str_notifytype' => DI::l10n()->t('Notification type:'),
-                                               '$notify_type' => $notif['notify_type'],
-                                               '$dfrn_text'   => $dfrn_text,
-                                               '$dfrn_id'     => $notif['dfrn_id'],
-                                               '$uid'         => $notif['uid'],
-                                               '$intro_id'    => $notif['intro_id'],
-                                               '$contact_id'  => $notif['contact_id'],
-                                               '$photo'       => $notif['photo'],
-                                               '$fullname'    => $notif['name'],
-                                               '$location'    => $notif['location'],
-                                               '$lbl_location'=> DI::l10n()->t('Location:'),
-                                               '$about'       => $notif['about'],
-                                               '$lbl_about'   => DI::l10n()->t('About:'),
-                                               '$keywords'    => $notif['keywords'],
-                                               '$lbl_keywords'=> DI::l10n()->t('Tags:'),
-                                               '$gender'      => $notif['gender'],
-                                               '$lbl_gender'  => DI::l10n()->t('Gender:'),
-                                               '$hidden'      => ['hidden', DI::l10n()->t('Hide this contact from others'), ($notif['hidden'] == 1), ''],
-                                               '$url'         => $notif['url'],
-                                               '$zrl'         => $notif['zrl'],
-                                               '$lbl_url'     => DI::l10n()->t('Profile URL'),
-                                               '$addr'        => $notif['addr'],
-                                               '$lbl_knowyou' => $lbl_knowyou,
-                                               '$lbl_network' => DI::l10n()->t('Network:'),
-                                               '$network'     => ContactSelector::networkToName($notif['network'], $notif['url']),
-                                               '$knowyou'     => $knowyou,
-                                               '$approve'     => DI::l10n()->t('Approve'),
-                                               '$note'        => $notif['note'],
-                                               '$ignore'      => DI::l10n()->t('Ignore'),
-                                               '$discard'     => $discard,
-                                               '$action'      => $action,
-                                       ]);
-                                       break;
-                       }
-               }
-
-               if (count($notifs['notifications']) == 0) {
-                       info(DI::l10n()->t('No introductions.') . EOL);
-               }
-
-               // Normal notifications (no introductions)
-       } elseif (!empty($notifs['notifications'])) {
-               // Loop trough ever notification This creates an array with the output html for each
-               // notification and apply the correct template according to the notificationtype (label).
-               foreach ($notifs['notifications'] as $notif) {
-                       $notification_templates = [
-                               'like'        => 'notifications_likes_item.tpl',
-                               'dislike'     => 'notifications_dislikes_item.tpl',
-                               'attend'      => 'notifications_attend_item.tpl',
-                               'attendno'    => 'notifications_attend_item.tpl',
-                               'attendmaybe' => 'notifications_attend_item.tpl',
-                               'friend'      => 'notifications_friends_item.tpl',
-                               'comment'     => 'notifications_comments_item.tpl',
-                               'post'        => 'notifications_posts_item.tpl',
-                               'notify'      => 'notify.tpl',
-                       ];
-
-                       $tpl_notif = Renderer::getMarkupTemplate($notification_templates[$notif['label']]);
-
-                       $notif_content[] = Renderer::replaceMacros($tpl_notif, [
-                               '$item_label' => $notif['label'],
-                               '$item_link'  => $notif['link'],
-                               '$item_image' => $notif['image'],
-                               '$item_url'   => $notif['url'],
-                               '$item_text'  => $notif['text'],
-                               '$item_when'  => $notif['when'],
-                               '$item_ago'   => $notif['ago'],
-                               '$item_seen'  => $notif['seen'],
-                       ]);
-               }
-       } else {
-               $notif_nocontent = DI::l10n()->t('No more %s notifications.', $notifs['ident']);
-       }
-
-       $o .= Renderer::replaceMacros($notif_tpl, [
-               '$notif_header'    => $notif_header,
-               '$tabs'            => $tabs,
-               '$notif_content'   => $notif_content,
-               '$notif_nocontent' => $notif_nocontent,
-               '$notif_show_lnk'  => $notif_show_lnk,
-               '$notif_paginate'  => $pager->renderMinimal(count($notif_content))
-       ]);
-
-       return $o;
-}
-
-/**
- * List of pages for the Notifications TabBar
- *
- * @param string $selected The selected notification tab
- *
- * @return array with with notifications TabBar data
- * @throws Exception
- */
-function getTabs(string $selected = '')
-{
-       $tabs = [];
-
-       foreach (URL_TYPES as $type => $url) {
-               $tabs[] = [
-                       'label'     => DI::l10n()->t(PRINT_TYPES[$type]),
-                       'url'       => 'notifications/' . $url,
-                       'sel'       => (($selected == $url) ? 'active' : ''),
-                       'id'        => $type . '-tab',
-                       'accesskey' => ACCESS_KEYS[$type],
-               ];
-       }
-
-       return $tabs;
-}
index 5b8d22b655fa7ec8fd9103f5b5045643ac77ecb8..0733bbc96001f5e1fe0d98afd04241a5d166145f 100644 (file)
@@ -21,6 +21,7 @@ use Friendica\Model\Item;
 use Friendica\Model\Photo;
 use Friendica\Model\Profile;
 use Friendica\Model\User;
+use Friendica\Module\BaseProfile;
 use Friendica\Network\Probe;
 use Friendica\Object\Image;
 use Friendica\Protocol\Activity;
@@ -914,7 +915,7 @@ function photos_content(App $a)
 
        // tabs
        $is_owner = (local_user() && (local_user() == $owner_uid));
-       $o .= Profile::getTabs($a, 'photos', $is_owner, $a->data['user']['nickname']);
+       $o .= BaseProfile::getTabsHTML($a, 'photos', $is_owner, $a->data['user']['nickname']);
 
        // Display upload form
        if ($datatype === 'upload') {
index 4890197074ca93ecc780364d5d10310aa07bd1d3..dd57ba34d68eb3308fb3ca8847b038333410723b 100644 (file)
@@ -41,7 +41,7 @@ use Friendica\Util\XML;
  *            "birthdays-today": 0,
  *            "groups": [ ],
  *            "forums": [ ],
- *            "notify": 0,
+ *            "notification": 0,
  *            "notifications": [ ],
  *            "sysmsgs": {
  *                "notice": [ ],
@@ -351,7 +351,7 @@ function ping_init(App $a)
        if ($format == 'json') {
                $data['groups'] = $groups_unseen;
                $data['forums'] = $forums_unseen;
-               $data['notify'] = $sysnotify_count + $intro_count + $register_count;
+               $data['notification'] = $sysnotify_count + $intro_count + $register_count;
                $data['notifications'] = $notifications;
                $data['sysmsgs'] = [
                        'notice' => $sysmsgs,
@@ -433,7 +433,7 @@ function ping_get_notifications($uid)
                                $notification["message"] = $notification["msg_cache"];
                        } else {
                                $notification["name"] = strip_tags(BBCode::convert($notification["name"]));
-                               $notification["message"] = format_notification_message($notification["name"], strip_tags(BBCode::convert($notification["msg"])));
+                               $notification["message"] = Friendica\Model\Notify::formatMessage($notification["name"], strip_tags(BBCode::convert($notification["msg"])));
 
                                q(
                                        "UPDATE `notify` SET `name_cache` = '%s', `msg_cache` = '%s' WHERE `id` = %d",
@@ -443,7 +443,7 @@ function ping_get_notifications($uid)
                                );
                        }
 
-                       $notification["href"] = DI::baseUrl() . "/notify/view/" . $notification["id"];
+                       $notification["href"] = DI::baseUrl() . "/notification/view/" . $notification["id"];
 
                        if ($notification["visible"]
                                && !$notification["deleted"]
index 8e7d63418afba2271c32b294fa15a2cef2240277..d8941e51ade5c6de1caa52d71197d6693bc06c8e 100644 (file)
@@ -67,7 +67,7 @@ function poco_init(App $a) {
 
        if (! $system_mode && ! $global) {
                $users = q("SELECT `user`.*,`profile`.`hide-friends` from user left join profile on `user`.`uid` = `profile`.`uid`
-                       where `user`.`nickname` = '%s' and `profile`.`is-default` = 1 limit 1",
+                       where `user`.`nickname` = '%s' limit 1",
                        DBA::escape($nickname)
                );
                if (! DBA::isResult($users) || $users[0]['hidewall'] || $users[0]['hide-friends']) {
@@ -140,7 +140,7 @@ function poco_init(App $a) {
                                `profile`.`postal-code` AS `ppostalcode`, `profile`.`country-name` AS `pcountry`, `user`.`account-type`
                        FROM `contact` INNER JOIN `profile` ON `profile`.`uid` = `contact`.`uid`
                                INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
-                       WHERE `self` = 1 AND `profile`.`is-default`
+                       WHERE `self` = 1
                        AND `contact`.`uid` IN (SELECT `uid` FROM `pconfig` WHERE `cat` = 'system' AND `k` = 'suggestme' AND `v` = 1) LIMIT %d, %d",
                        intval($startIndex),
                        intval($itemsPerPage)
diff --git a/mod/profiles.php b/mod/profiles.php
deleted file mode 100644 (file)
index 53da851..0000000
+++ /dev/null
@@ -1,675 +0,0 @@
-<?php
-/**
- * @file mod/profiles.php
- */
-
-use Friendica\App;
-use Friendica\BaseModule;
-use Friendica\Content\ContactSelector;
-use Friendica\Content\Feature;
-use Friendica\Content\Nav;
-use Friendica\Core\Hook;
-use Friendica\Core\Renderer;
-use Friendica\Core\Worker;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
-use Friendica\Model\Profile;
-use Friendica\Model\User;
-use Friendica\Module\Security\Login;
-use Friendica\Network\Probe;
-use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Strings;
-use Friendica\Util\Temporal;
-
-function profiles_init(App $a) {
-
-       Nav::setSelected('profiles');
-
-       if (! local_user()) {
-               return;
-       }
-
-       if (($a->argc > 2) && ($a->argv[1] === "drop") && intval($a->argv[2])) {
-               $r = q("SELECT * FROM `profile` WHERE `id` = %d AND `uid` = %d AND `is-default` = 0 LIMIT 1",
-                       intval($a->argv[2]),
-                       intval(local_user())
-               );
-               if (! DBA::isResult($r)) {
-                       notice(DI::l10n()->t('Profile not found.') . EOL);
-                       DI::baseUrl()->redirect('profiles');
-                       return; // NOTREACHED
-               }
-
-               BaseModule::checkFormSecurityTokenRedirectOnError('/profiles', 'profile_drop', 't');
-
-               // move every contact using this profile as their default to the user default
-
-               q("UPDATE `contact` SET `profile-id` = (SELECT `profile`.`id` AS `profile-id` FROM `profile` WHERE `profile`.`is-default` = 1 AND `profile`.`uid` = %d LIMIT 1) WHERE `profile-id` = %d AND `uid` = %d ",
-                       intval(local_user()),
-                       intval($a->argv[2]),
-                       intval(local_user())
-               );
-               q("DELETE FROM `profile` WHERE `id` = %d AND `uid` = %d",
-                       intval($a->argv[2]),
-                       intval(local_user())
-               );
-               if (DBA::isResult($r)) {
-                       info(DI::l10n()->t('Profile deleted.').EOL);
-               }
-
-               DI::baseUrl()->redirect('profiles');
-               return; // NOTREACHED
-       }
-
-       if (($a->argc > 1) && ($a->argv[1] === 'new')) {
-
-               BaseModule::checkFormSecurityTokenRedirectOnError('/profiles', 'profile_new', 't');
-
-               $r0 = q("SELECT `id` FROM `profile` WHERE `uid` = %d",
-                       intval(local_user()));
-
-               $num_profiles = (DBA::isResult($r0) ? count($r0) : 0);
-
-               $name = DI::l10n()->t('Profile-') . ($num_profiles + 1);
-
-               $r1 = q("SELECT `name`, `photo`, `thumb` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1",
-                       intval(local_user()));
-
-               q("INSERT INTO `profile` (`uid` , `profile-name` , `name`, `photo`, `thumb`)
-                       VALUES ( %d, '%s', '%s', '%s', '%s' )",
-                       intval(local_user()),
-                       DBA::escape($name),
-                       DBA::escape($r1[0]['name']),
-                       DBA::escape($r1[0]['photo']),
-                       DBA::escape($r1[0]['thumb'])
-               );
-
-               $r3 = q("SELECT `id` FROM `profile` WHERE `uid` = %d AND `profile-name` = '%s' LIMIT 1",
-                       intval(local_user()),
-                       DBA::escape($name)
-               );
-
-               info(DI::l10n()->t('New profile created.') . EOL);
-               if (DBA::isResult($r3) && count($r3) == 1) {
-                       DI::baseUrl()->redirect('profiles/' . $r3[0]['id']);
-               }
-
-               DI::baseUrl()->redirect('profiles');
-       }
-
-       if (($a->argc > 2) && ($a->argv[1] === 'clone')) {
-
-               BaseModule::checkFormSecurityTokenRedirectOnError('/profiles', 'profile_clone', 't');
-
-               $r0 = q("SELECT `id` FROM `profile` WHERE `uid` = %d",
-                       intval(local_user()));
-
-               $num_profiles = (DBA::isResult($r0) ? count($r0) : 0);
-
-               $name = DI::l10n()->t('Profile-') . ($num_profiles + 1);
-               $r1 = q("SELECT * FROM `profile` WHERE `uid` = %d AND `id` = %d LIMIT 1",
-                       intval(local_user()),
-                       intval($a->argv[2])
-               );
-               if(! DBA::isResult($r1)) {
-                       notice(DI::l10n()->t('Profile unavailable to clone.') . EOL);
-                       exit();
-               }
-               unset($r1[0]['id']);
-               $r1[0]['is-default'] = 0;
-               $r1[0]['publish'] = 0;
-               $r1[0]['net-publish'] = 0;
-               $r1[0]['profile-name'] = DBA::escape($name);
-
-               DBA::insert('profile', $r1[0]);
-
-               $r3 = q("SELECT `id` FROM `profile` WHERE `uid` = %d AND `profile-name` = '%s' LIMIT 1",
-                       intval(local_user()),
-                       DBA::escape($name)
-               );
-               info(DI::l10n()->t('New profile created.') . EOL);
-               if ((DBA::isResult($r3)) && (count($r3) == 1)) {
-                       DI::baseUrl()->redirect('profiles/'.$r3[0]['id']);
-               }
-
-               DI::baseUrl()->redirect('profiles');
-
-               return; // NOTREACHED
-       }
-
-
-       if (($a->argc > 1) && (intval($a->argv[1]))) {
-               $r = q("SELECT id FROM `profile` WHERE `id` = %d AND `uid` = %d LIMIT 1",
-                       intval($a->argv[1]),
-                       intval(local_user())
-               );
-               if (! DBA::isResult($r)) {
-                       notice(DI::l10n()->t('Profile not found.') . EOL);
-                       exit();
-               }
-
-               Profile::load($a, $a->user['nickname'], $r[0]['id']);
-       }
-}
-
-function profile_clean_keywords($keywords)
-{
-       $keywords = str_replace(",", " ", $keywords);
-       $keywords = explode(" ", $keywords);
-
-       $cleaned = [];
-       foreach ($keywords as $keyword) {
-               $keyword = trim(strtolower($keyword));
-               $keyword = trim($keyword, "#");
-               if ($keyword != "") {
-                       $cleaned[] = $keyword;
-               }
-       }
-
-       $keywords = implode(", ", $cleaned);
-
-       return $keywords;
-}
-
-function profiles_post(App $a) {
-
-       if (! local_user()) {
-               notice(DI::l10n()->t('Permission denied.') . EOL);
-               return;
-       }
-
-       $namechanged = false;
-
-       Hook::callAll('profile_post', $_POST);
-
-       if (($a->argc > 1) && ($a->argv[1] !== "new") && intval($a->argv[1])) {
-               $orig = q("SELECT * FROM `profile` WHERE `id` = %d AND `uid` = %d LIMIT 1",
-                       intval($a->argv[1]),
-                       intval(local_user())
-               );
-               if (! DBA::isResult($orig)) {
-                       notice(DI::l10n()->t('Profile not found.') . EOL);
-                       return;
-               }
-
-               BaseModule::checkFormSecurityTokenRedirectOnError('/profiles', 'profile_edit');
-
-               $is_default = (($orig[0]['is-default']) ? 1 : 0);
-
-               $profile_name = Strings::escapeTags(trim($_POST['profile_name']));
-               if (! strlen($profile_name)) {
-                       notice(DI::l10n()->t('Profile Name is required.') . EOL);
-                       return;
-               }
-
-               $dob = !empty($_POST['dob']) ? Strings::escapeHtml(trim($_POST['dob'])) : '0000-00-00';
-
-               $y = substr($dob, 0, 4);
-               if ((! ctype_digit($y)) || ($y < 1900)) {
-                       $ignore_year = true;
-               } else {
-                       $ignore_year = false;
-               }
-               if (!in_array($dob, ['0000-00-00', DBA::NULL_DATE])) {
-                       if (strpos($dob, '0000-') === 0 || strpos($dob, '0001-') === 0) {
-                               $ignore_year = true;
-                               $dob = substr($dob, 5);
-                       }
-
-                       if ($ignore_year) {
-                               $dob = '0000-' . DateTimeFormat::utc('1900-' . $dob, 'm-d');
-                       } else {
-                               $dob = DateTimeFormat::utc($dob, 'Y-m-d');
-                       }
-               }
-
-               $name = Strings::escapeTags(trim($_POST['name']));
-
-               if (! strlen($name)) {
-                       $name = '[No Name]';
-               }
-
-               if ($orig[0]['name'] != $name) {
-                       $namechanged = true;
-               }
-
-               $pdesc = Strings::escapeTags(trim($_POST['pdesc'] ?? ''));
-               $gender = Strings::escapeTags(trim($_POST['gender'] ?? ''));
-               $address = Strings::escapeTags(trim($_POST['address'] ?? ''));
-               $locality = Strings::escapeTags(trim($_POST['locality'] ?? ''));
-               $region = Strings::escapeTags(trim($_POST['region'] ?? ''));
-               $postal_code = Strings::escapeTags(trim($_POST['postal_code'] ?? ''));
-               $country_name = Strings::escapeTags(trim($_POST['country_name'] ?? ''));
-               $pub_keywords = profile_clean_keywords(Strings::escapeTags(trim($_POST['pub_keywords'] ?? '')));
-               $prv_keywords = profile_clean_keywords(Strings::escapeTags(trim($_POST['prv_keywords'] ?? '')));
-               $marital = Strings::escapeTags(trim($_POST['marital'] ?? ''));
-               $howlong = Strings::escapeTags(trim($_POST['howlong'] ?? ''));
-
-               $with = (!empty($_POST['with']) ? Strings::escapeTags(trim($_POST['with'])) : '');
-
-               if (! strlen($howlong)) {
-                       $howlong = DBA::NULL_DATETIME;
-               } else {
-                       $howlong = DateTimeFormat::convert($howlong, 'UTC', date_default_timezone_get());
-               }
-               // linkify the relationship target if applicable
-
-               $withchanged = false;
-
-               if (strlen($with)) {
-                       if ($with != strip_tags($orig[0]['with'])) {
-                               $withchanged = true;
-                               $prf = '';
-                               $lookup = $with;
-                               if (strpos($lookup, '@') === 0) {
-                                       $lookup = substr($lookup, 1);
-                               }
-                               $lookup = str_replace('_',' ', $lookup);
-                               if (strpos($lookup, '@') || (strpos($lookup, 'http://'))) {
-                                       $newname = $lookup;
-                                       $links = @Probe::lrdd($lookup);
-                                       if (count($links)) {
-                                               foreach ($links as $link) {
-                                                       if ($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') {
-                                                               $prf = $link['@attributes']['href'];
-                                                       }
-                                               }
-                                       }
-                               } else {
-                                       $newname = $lookup;
-
-                                       $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `uid` = %d LIMIT 1",
-                                               DBA::escape($newname),
-                                               intval(local_user())
-                                       );
-                                       if (! DBA::isResult($r)) {
-                                               $r = q("SELECT * FROM `contact` WHERE `nick` = '%s' AND `uid` = %d LIMIT 1",
-                                                       DBA::escape($lookup),
-                                                       intval(local_user())
-                                               );
-                                       }
-                                       if (DBA::isResult($r)) {
-                                               $prf = $r[0]['url'];
-                                               $newname = $r[0]['name'];
-                                       }
-                               }
-
-                               if ($prf) {
-                                       $with = str_replace($lookup, '<a href="' . $prf . '">' . $newname . '</a>', $with);
-                                       if (strpos($with, '@') === 0) {
-                                               $with = substr($with, 1);
-                                       }
-                               }
-                       } else {
-                               $with = $orig[0]['with'];
-                       }
-               }
-
-               /// @TODO Not flexible enough for later expansion, let's have more OOP here
-               $sexual = Strings::escapeTags(trim($_POST['sexual']));
-               $xmpp = Strings::escapeTags(trim($_POST['xmpp']));
-               $homepage = Strings::escapeTags(trim($_POST['homepage']));
-               if ((strpos($homepage, 'http') !== 0) && (strlen($homepage))) {
-                       // neither http nor https in URL, add them
-                       $homepage = 'http://'.$homepage;
-               }
-               $hometown = Strings::escapeTags(trim($_POST['hometown']));
-               $politic = Strings::escapeTags(trim($_POST['politic']));
-               $religion = Strings::escapeTags(trim($_POST['religion']));
-
-               $likes = Strings::escapeHtml(trim($_POST['likes']));
-               $dislikes = Strings::escapeHtml(trim($_POST['dislikes']));
-
-               $about = Strings::escapeHtml(trim($_POST['about']));
-               $interest = Strings::escapeHtml(trim($_POST['interest']));
-               $contact = Strings::escapeHtml(trim($_POST['contact']));
-               $music = Strings::escapeHtml(trim($_POST['music']));
-               $book = Strings::escapeHtml(trim($_POST['book']));
-               $tv = Strings::escapeHtml(trim($_POST['tv']));
-               $film = Strings::escapeHtml(trim($_POST['film']));
-               $romance = Strings::escapeHtml(trim($_POST['romance']));
-               $work = Strings::escapeHtml(trim($_POST['work']));
-               $education = Strings::escapeHtml(trim($_POST['education']));
-
-               $hide_friends = (($_POST['hide-friends'] == 1) ? 1: 0);
-
-               DI::pConfig()->set(local_user(), 'system', 'detailled_profile', !empty($_POST['detailed_profile']) ? 1: 0);
-
-               $changes = [];
-               if ($is_default) {
-                       if ($marital != $orig[0]['marital']) {
-                               $changes[] = '[color=#ff0000]&hearts;[/color] ' . DI::l10n()->t('Marital Status');
-                       }
-                       if ($withchanged) {
-                               $changes[] = '[color=#ff0000]&hearts;[/color] ' . DI::l10n()->t('Romantic Partner');
-                       }
-                       if ($likes != $orig[0]['likes']) {
-                               $changes[] = DI::l10n()->t('Likes');
-                       }
-                       if ($dislikes != $orig[0]['dislikes']) {
-                               $changes[] = DI::l10n()->t('Dislikes');
-                       }
-                       if ($work != $orig[0]['work']) {
-                               $changes[] = DI::l10n()->t('Work/Employment');
-                       }
-                       if ($religion != $orig[0]['religion']) {
-                               $changes[] = DI::l10n()->t('Religion');
-                       }
-                       if ($politic != $orig[0]['politic']) {
-                               $changes[] = DI::l10n()->t('Political Views');
-                       }
-                       if ($gender != $orig[0]['gender']) {
-                               $changes[] = DI::l10n()->t('Gender');
-                       }
-                       if ($sexual != $orig[0]['sexual']) {
-                               $changes[] = DI::l10n()->t('Sexual Preference');
-                       }
-                       if ($xmpp != $orig[0]['xmpp']) {
-                               $changes[] = DI::l10n()->t('XMPP');
-                       }
-                       if ($homepage != $orig[0]['homepage']) {
-                               $changes[] = DI::l10n()->t('Homepage');
-                       }
-                       if ($interest != $orig[0]['interest']) {
-                               $changes[] = DI::l10n()->t('Interests');
-                       }
-                       if ($address != $orig[0]['address']) {
-                               $changes[] = DI::l10n()->t('Address');
-                               // New address not sent in notifications, potential privacy issues
-                               // in case this leaks to unintended recipients. Yes, it's in the public
-                               // profile but that doesn't mean we have to broadcast it to everybody.
-                       }
-                       if ($locality != $orig[0]['locality'] || $region != $orig[0]['region']
-                               || $country_name != $orig[0]['country-name']) {
-                               $changes[] = DI::l10n()->t('Location');
-                       }
-               }
-
-               $r = q("UPDATE `profile`
-                       SET `profile-name` = '%s',
-                       `name` = '%s',
-                       `pdesc` = '%s',
-                       `gender` = '%s',
-                       `dob` = '%s',
-                       `address` = '%s',
-                       `locality` = '%s',
-                       `region` = '%s',
-                       `postal-code` = '%s',
-                       `country-name` = '%s',
-                       `marital` = '%s',
-                       `with` = '%s',
-                       `howlong` = '%s',
-                       `sexual` = '%s',
-                       `xmpp` = '%s',
-                       `homepage` = '%s',
-                       `hometown` = '%s',
-                       `politic` = '%s',
-                       `religion` = '%s',
-                       `pub_keywords` = '%s',
-                       `prv_keywords` = '%s',
-                       `likes` = '%s',
-                       `dislikes` = '%s',
-                       `about` = '%s',
-                       `interest` = '%s',
-                       `contact` = '%s',
-                       `music` = '%s',
-                       `book` = '%s',
-                       `tv` = '%s',
-                       `film` = '%s',
-                       `romance` = '%s',
-                       `work` = '%s',
-                       `education` = '%s',
-                       `hide-friends` = %d
-                       WHERE `id` = %d AND `uid` = %d",
-                       DBA::escape($profile_name),
-                       DBA::escape($name),
-                       DBA::escape($pdesc),
-                       DBA::escape($gender),
-                       DBA::escape($dob),
-                       DBA::escape($address),
-                       DBA::escape($locality),
-                       DBA::escape($region),
-                       DBA::escape($postal_code),
-                       DBA::escape($country_name),
-                       DBA::escape($marital),
-                       DBA::escape($with),
-                       DBA::escape($howlong),
-                       DBA::escape($sexual),
-                       DBA::escape($xmpp),
-                       DBA::escape($homepage),
-                       DBA::escape($hometown),
-                       DBA::escape($politic),
-                       DBA::escape($religion),
-                       DBA::escape($pub_keywords),
-                       DBA::escape($prv_keywords),
-                       DBA::escape($likes),
-                       DBA::escape($dislikes),
-                       DBA::escape($about),
-                       DBA::escape($interest),
-                       DBA::escape($contact),
-                       DBA::escape($music),
-                       DBA::escape($book),
-                       DBA::escape($tv),
-                       DBA::escape($film),
-                       DBA::escape($romance),
-                       DBA::escape($work),
-                       DBA::escape($education),
-                       intval($hide_friends),
-                       intval($a->argv[1]),
-                       intval(local_user())
-               );
-
-               /// @TODO decide to use DBA::isResult() here and check $r
-               if ($r) {
-                       info(DI::l10n()->t('Profile updated.') . EOL);
-               }
-
-               if ($is_default) {
-                       if ($namechanged) {
-                               q("UPDATE `user` set `username` = '%s' where `uid` = %d",
-                                       DBA::escape($name),
-                                       intval(local_user())
-                               );
-                       }
-
-                       Contact::updateSelfFromUserID(local_user());
-
-                       // Update global directory in background
-                       $url = $_SESSION['my_url'];
-                       if ($url && strlen(DI::config()->get('system', 'directory'))) {
-                               Worker::add(PRIORITY_LOW, "Directory", $url);
-                       }
-
-                       Worker::add(PRIORITY_LOW, 'ProfileUpdate', local_user());
-
-                       // Update the global contact for the user
-                       GContact::updateForUser(local_user());
-               }
-       }
-}
-
-function profiles_content(App $a) {
-
-       if (! local_user()) {
-               notice(DI::l10n()->t('Permission denied.') . EOL);
-               return Login::form();
-       }
-
-       $o = '';
-
-       if (($a->argc > 1) && (intval($a->argv[1]))) {
-               $r = q("SELECT * FROM `profile` WHERE `id` = %d AND `uid` = %d LIMIT 1",
-                       intval($a->argv[1]),
-                       intval(local_user())
-               );
-               if (! DBA::isResult($r)) {
-                       notice(DI::l10n()->t('Profile not found.') . EOL);
-                       return;
-               }
-
-               DI::page()['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('profed_head.tpl'), [
-                       '$baseurl' => DI::baseUrl()->get(true),
-               ]);
-
-               $opt_tpl = Renderer::getMarkupTemplate("profile-hide-friends.tpl");
-               $hide_friends = Renderer::replaceMacros($opt_tpl,[
-                       '$yesno' => [
-                               'hide-friends', //Name
-                               DI::l10n()->t('Hide contacts and friends:'), //Label
-                               !!$r[0]['hide-friends'], //Value
-                               '', //Help string
-                               [DI::l10n()->t('No'), DI::l10n()->t('Yes')] //Off - On strings
-                       ],
-                       '$desc' => DI::l10n()->t('Hide your contact/friend list from viewers of this profile?'),
-                       '$yes_str' => DI::l10n()->t('Yes'),
-                       '$no_str' => DI::l10n()->t('No'),
-                       '$yes_selected' => (($r[0]['hide-friends']) ? " checked=\"checked\" " : ""),
-                       '$no_selected' => (($r[0]['hide-friends'] == 0) ? " checked=\"checked\" " : "")
-               ]);
-
-               $personal_account = !(in_array($a->user["page-flags"],
-                                       [User::PAGE_FLAGS_COMMUNITY, User::PAGE_FLAGS_PRVGROUP]));
-
-               $detailed_profile = (DI::pConfig()->get(local_user(), 'system', 'detailled_profile') AND $personal_account);
-
-               $is_default = (($r[0]['is-default']) ? 1 : 0);
-               $tpl = Renderer::getMarkupTemplate("profile_edit.tpl");
-               $o .= Renderer::replaceMacros($tpl, [
-                       '$personal_account' => $personal_account,
-                       '$detailled_profile' => $detailed_profile,
-
-                       '$details' => [
-                               'detailed_profile', //Name
-                               DI::l10n()->t('Show more profile fields:'), //Label
-                               $detailed_profile, //Value
-                               '', //Help string
-                               [DI::l10n()->t('No'), DI::l10n()->t('Yes')] //Off - On strings
-                       ],
-
-                       '$multi_profiles'               => Feature::isEnabled(local_user(), 'multi_profiles'),
-                       '$form_security_token'          => BaseModule::getFormSecurityToken("profile_edit"),
-                       '$form_security_token_photo'    => BaseModule::getFormSecurityToken("profile_photo"),
-                       '$profile_clone_link'           => ((Feature::isEnabled(local_user(), 'multi_profiles')) ? 'profiles/clone/' . $r[0]['id'] . '?t=' . BaseModule::getFormSecurityToken("profile_clone") : ""),
-                       '$profile_drop_link'            => 'profiles/drop/' . $r[0]['id'] . '?t=' . BaseModule::getFormSecurityToken("profile_drop"),
-
-                       '$profile_action' => DI::l10n()->t('Profile Actions'),
-                       '$banner'       => DI::l10n()->t('Edit Profile Details'),
-                       '$submit'       => DI::l10n()->t('Submit'),
-                       '$profpic'      => DI::l10n()->t('Change Profile Photo'),
-                       '$profpiclink'  => '/photos/' . $a->user['nickname'],
-                       '$viewprof'     => DI::l10n()->t('View this profile'),
-                       '$viewallprof'  => DI::l10n()->t('View all profiles'),
-                       '$editvis'      => DI::l10n()->t('Edit visibility'),
-                       '$cr_prof'      => DI::l10n()->t('Create a new profile using these settings'),
-                       '$cl_prof'      => DI::l10n()->t('Clone this profile'),
-                       '$del_prof'     => DI::l10n()->t('Delete this profile'),
-
-                       '$lbl_basic_section' => DI::l10n()->t('Basic information'),
-                       '$lbl_picture_section' => DI::l10n()->t('Profile picture'),
-                       '$lbl_location_section' => DI::l10n()->t('Location'),
-                       '$lbl_preferences_section' => DI::l10n()->t('Preferences'),
-                       '$lbl_status_section' => DI::l10n()->t('Status information'),
-                       '$lbl_about_section' => DI::l10n()->t('Additional information'),
-                       '$lbl_interests_section' => DI::l10n()->t('Interests'),
-                       '$lbl_personal_section' => DI::l10n()->t('Personal'),
-                       '$lbl_relation_section' => DI::l10n()->t('Relation'),
-                       '$lbl_miscellaneous_section' => DI::l10n()->t('Miscellaneous'),
-
-                       '$lbl_profile_photo' => DI::l10n()->t('Upload Profile Photo'),
-                       '$lbl_gender' => DI::l10n()->t('Your Gender:'),
-                       '$lbl_marital' => DI::l10n()->t('<span class="heart">&hearts;</span> Marital Status:'),
-                       '$lbl_sexual' => DI::l10n()->t('Sexual Preference:'),
-                       '$lbl_ex2' => DI::l10n()->t('Example: fishing photography software'),
-
-                       '$disabled' => (($is_default) ? 'onclick="return false;" style="color: #BBBBFF;"' : ''),
-                       '$baseurl' => DI::baseUrl()->get(true),
-                       '$profile_id' => $r[0]['id'],
-                       '$profile_name' => ['profile_name', DI::l10n()->t('Profile Name:'), $r[0]['profile-name'], DI::l10n()->t('Required'), '*'],
-                       '$is_default'   => $is_default,
-                       '$default' => (($is_default) ? '<p id="profile-edit-default-desc">' . DI::l10n()->t('This is your <strong>public</strong> profile.<br />It <strong>may</strong> be visible to anybody using the internet.') . '</p>' : ""),
-                       '$name' => ['name', DI::l10n()->t('Your Full Name:'), $r[0]['name']],
-                       '$pdesc' => ['pdesc', DI::l10n()->t('Title/Description:'), $r[0]['pdesc']],
-                       '$dob' => Temporal::getDateofBirthField($r[0]['dob'], $a->user['timezone']),
-                       '$hide_friends' => $hide_friends,
-                       '$address' => ['address', DI::l10n()->t('Street Address:'), $r[0]['address']],
-                       '$locality' => ['locality', DI::l10n()->t('Locality/City:'), $r[0]['locality']],
-                       '$region' => ['region', DI::l10n()->t('Region/State:'), $r[0]['region']],
-                       '$postal_code' => ['postal_code', DI::l10n()->t('Postal/Zip Code:'), $r[0]['postal-code']],
-                       '$country_name' => ['country_name', DI::l10n()->t('Country:'), $r[0]['country-name']],
-                       '$age' => ((intval($r[0]['dob'])) ? '(' . DI::l10n()->t('Age: ') . DI::l10n()->tt('%d year old', '%d years old', Temporal::getAgeByTimezone($r[0]['dob'], $a->user['timezone'])) . ')' : ''),
-                       '$gender' => DI::l10n()->t(ContactSelector::gender($r[0]['gender'])),
-                       '$marital' => ['selector' => ContactSelector::maritalStatus($r[0]['marital']), 'value' => DI::l10n()->t($r[0]['marital'])],
-                       '$with' => ['with', DI::l10n()->t("Who: \x28if applicable\x29"), strip_tags($r[0]['with']), DI::l10n()->t('Examples: cathy123, Cathy Williams, cathy@example.com')],
-                       '$howlong' => ['howlong', DI::l10n()->t('Since [date]:'), ($r[0]['howlong'] <= DBA::NULL_DATETIME ? '' : DateTimeFormat::local($r[0]['howlong']))],
-                       '$sexual' => ['selector' => ContactSelector::sexualPreference($r[0]['sexual']), 'value' => DI::l10n()->t($r[0]['sexual'])],
-                       '$about' => ['about', DI::l10n()->t('Tell us about yourself...'), $r[0]['about']],
-                       '$xmpp' => ['xmpp', DI::l10n()->t("XMPP \x28Jabber\x29 address:"), $r[0]['xmpp'], DI::l10n()->t("The XMPP address will be propagated to your contacts so that they can follow you.")],
-                       '$homepage' => ['homepage', DI::l10n()->t('Homepage URL:'), $r[0]['homepage']],
-                       '$hometown' => ['hometown', DI::l10n()->t('Hometown:'), $r[0]['hometown']],
-                       '$politic' => ['politic', DI::l10n()->t('Political Views:'), $r[0]['politic']],
-                       '$religion' => ['religion', DI::l10n()->t('Religious Views:'), $r[0]['religion']],
-                       '$pub_keywords' => ['pub_keywords', DI::l10n()->t('Public Keywords:'), $r[0]['pub_keywords'], DI::l10n()->t("\x28Used for suggesting potential friends, can be seen by others\x29")],
-                       '$prv_keywords' => ['prv_keywords', DI::l10n()->t('Private Keywords:'), $r[0]['prv_keywords'], DI::l10n()->t("\x28Used for searching profiles, never shown to others\x29")],
-                       '$likes' => ['likes', DI::l10n()->t('Likes:'), $r[0]['likes']],
-                       '$dislikes' => ['dislikes', DI::l10n()->t('Dislikes:'), $r[0]['dislikes']],
-                       '$music' => ['music', DI::l10n()->t('Musical interests'), $r[0]['music']],
-                       '$book' => ['book', DI::l10n()->t('Books, literature'), $r[0]['book']],
-                       '$tv' => ['tv', DI::l10n()->t('Television'), $r[0]['tv']],
-                       '$film' => ['film', DI::l10n()->t('Film/dance/culture/entertainment'), $r[0]['film']],
-                       '$interest' => ['interest', DI::l10n()->t('Hobbies/Interests'), $r[0]['interest']],
-                       '$romance' => ['romance', DI::l10n()->t('Love/romance'), $r[0]['romance']],
-                       '$work' => ['work', DI::l10n()->t('Work/employment'), $r[0]['work']],
-                       '$education' => ['education', DI::l10n()->t('School/education'), $r[0]['education']],
-                       '$contact' => ['contact', DI::l10n()->t('Contact information and Social Networks'), $r[0]['contact']],
-               ]);
-
-               $arr = ['profile' => $r[0], 'entry' => $o];
-               Hook::callAll('profile_edit', $arr);
-
-               return $o;
-       } else {
-               // If we don't support multi profiles, don't display this list.
-               if (!Feature::isEnabled(local_user(), 'multi_profiles')) {
-                       $r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `is-default`=1",
-                               local_user()
-                       );
-                       if (DBA::isResult($r)) {
-                               //Go to the default profile.
-                               DI::baseUrl()->redirect('profiles/' . $r[0]['id']);
-                       }
-               }
-
-               $r = q("SELECT * FROM `profile` WHERE `uid` = %d",
-                       local_user());
-
-               if (DBA::isResult($r)) {
-
-                       $tpl = Renderer::getMarkupTemplate('profile_entry.tpl');
-
-                       $profiles = '';
-                       foreach ($r as $rr) {
-                               $profiles .= Renderer::replaceMacros($tpl, [
-                                       '$photo'        => DI::baseUrl()->remove($rr['thumb']),
-                                       '$id'           => $rr['id'],
-                                       '$alt'          => DI::l10n()->t('Profile Image'),
-                                       '$profile_name' => $rr['profile-name'],
-                                       '$visible'      => (($rr['is-default']) ? '<strong>' . DI::l10n()->t('visible to everybody') . '</strong>'
-                                               : '<a href="'.'profperm/'.$rr['id'].'" />' . DI::l10n()->t('Edit visibility') . '</a>')
-                               ]);
-                       }
-
-                       $tpl_header = Renderer::getMarkupTemplate('profile_listing_header.tpl');
-                       $o .= Renderer::replaceMacros($tpl_header,[
-                               '$header'      => DI::l10n()->t('Edit/Manage Profiles'),
-                               '$chg_photo'   => DI::l10n()->t('Change profile photo'),
-                               '$cr_new'      => DI::l10n()->t('Create New Profile'),
-                               '$cr_new_link' => 'profiles/new?t=' . BaseModule::getFormSecurityToken("profile_new"),
-                               '$profiles'    => $profiles
-                       ]);
-               }
-               return $o;
-       }
-
-}
diff --git a/mod/profperm.php b/mod/profperm.php
deleted file mode 100644 (file)
index f17d1d6..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-/**
- * @file mod/profperm.php
- */
-use Friendica\App;
-use Friendica\Core\Protocol;
-use Friendica\Content\Text\HTML;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Model\Profile;
-
-function profperm_init(App $a)
-{
-       if (!local_user()) {
-               return;
-       }
-
-       $which = $a->user['nickname'];
-       $profile = $a->argv[1];
-
-       Profile::load($a, $which, $profile);
-}
-
-
-function profperm_content(App $a) {
-
-       if (!local_user()) {
-               notice(DI::l10n()->t('Permission denied') . EOL);
-               return;
-       }
-
-
-       if ($a->argc < 2) {
-               notice(DI::l10n()->t('Invalid profile identifier.') . EOL );
-               return;
-       }
-
-       $o = '';
-
-       // Switch to text mod interface if we have more than 'n' contacts or group members
-
-       $switchtotext = DI::pConfig()->get(local_user(),'system','groupedit_image_limit');
-       if (is_null($switchtotext)) {
-               $switchtotext = DI::config()->get('system','groupedit_image_limit', 400);
-       }
-
-       if (($a->argc > 2) && intval($a->argv[1]) && intval($a->argv[2])) {
-               $r = q("SELECT `id` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `self` = 0
-                       AND `network` = '%s' AND `id` = %d AND `uid` = %d LIMIT 1",
-                       DBA::escape(Protocol::DFRN),
-                       intval($a->argv[2]),
-                       intval(local_user())
-               );
-
-               if (DBA::isResult($r)) {
-                       $change = intval($a->argv[2]);
-               }
-       }
-
-
-       if (($a->argc > 1) && (intval($a->argv[1]))) {
-               $r = q("SELECT * FROM `profile` WHERE `id` = %d AND `uid` = %d AND `is-default` = 0 LIMIT 1",
-                       intval($a->argv[1]),
-                       intval(local_user())
-               );
-               if (!DBA::isResult($r)) {
-                       notice(DI::l10n()->t('Invalid profile identifier.') . EOL );
-                       return;
-               }
-               $profile = $r[0];
-
-               $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `profile-id` = %d",
-                       intval(local_user()),
-                       intval($a->argv[1])
-               );
-
-               $ingroup = [];
-               if (DBA::isResult($r))
-                       foreach($r as $member)
-                               $ingroup[] = $member['id'];
-
-               $members = $r;
-
-               if (!empty($change)) {
-                       if (in_array($change,$ingroup)) {
-                               q("UPDATE `contact` SET `profile-id` = 0 WHERE `id` = %d AND `uid` = %d",
-                                       intval($change),
-                                       intval(local_user())
-                               );
-                       }
-                       else {
-                               q("UPDATE `contact` SET `profile-id` = %d WHERE `id` = %d AND `uid` = %d",
-                                       intval($a->argv[1]),
-                                       intval($change),
-                                       intval(local_user())
-                               );
-
-                       }
-
-                       $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `profile-id` = %d",
-                               intval(local_user()),
-                               intval($a->argv[1])
-                       );
-
-                       $members = $r;
-
-                       $ingroup = [];
-                       if (DBA::isResult($r))
-                               foreach($r as $member)
-                                       $ingroup[] = $member['id'];
-               }
-
-               $o .= '<h2>' . DI::l10n()->t('Profile Visibility Editor') . '</h2>';
-
-               $o .= '<h3>' . DI::l10n()->t('Profile') . ' \'' . $profile['profile-name'] . '\'</h3>';
-
-               $o .= '<div id="prof-edit-desc">' . DI::l10n()->t('Click on a contact to add or remove.') . '</div>';
-
-       }
-
-       $o .= '<div id="prof-update-wrapper">';
-       if (!empty($change))
-               $o = '';
-
-       $o .= '<div id="prof-members-title">';
-       $o .= '<h3>' . DI::l10n()->t('Visible To') . '</h3>';
-       $o .= '</div>';
-       $o .= '<div id="prof-members">';
-
-       $textmode = (($switchtotext && (count($members) > $switchtotext)) ? true : false);
-
-       foreach($members as $member) {
-               if ($member['url']) {
-                       $member['click'] = 'profChangeMember(' . $profile['id'] . ',' . $member['id'] . '); return true;';
-                       $o .= HTML::micropro($member,true,'mpprof', $textmode);
-               }
-       }
-       $o .= '</div><div id="prof-members-end"></div>';
-       $o .= '<hr id="prof-separator" />';
-
-       $o .= '<div id="prof-all-contcts-title">';
-       $o .= '<h3>' . DI::l10n()->t("All Contacts \x28with secure profile access\x29") . '</h3>';
-       $o .= '</div>';
-       $o .= '<div id="prof-all-contacts">';
-
-               $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `blocked` = 0 and `pending` = 0 and `self` = 0
-                       AND `network` = '%s' ORDER BY `name` ASC",
-                       intval(local_user()),
-                       DBA::escape(Protocol::DFRN)
-               );
-
-               if (DBA::isResult($r)) {
-                       $textmode = (($switchtotext && (count($r) > $switchtotext)) ? true : false);
-                       foreach($r as $member) {
-                               if (!in_array($member['id'],$ingroup)) {
-                                       $member['click'] = 'profChangeMember(' . $profile['id'] . ',' . $member['id'] . '); return true;';
-                                       $o .= HTML::micropro($member,true,'mpprof',$textmode);
-                               }
-                       }
-               }
-
-               $o .= '</div><div id="prof-all-contacts-end"></div>';
-
-       if (!empty($change)) {
-               echo $o;
-               exit();
-       }
-       $o .= '</div>';
-       return $o;
-
-}
index a3039b79845d88e2d4561f9a3e4a7be2c2673977..ed030723d3114eb8fc5016daed6085cb4e17a169 100644 (file)
@@ -27,7 +27,7 @@ function user_allow($hash)
 
        DBA::update('user', ['blocked' => false, 'verified' => true], ['uid' => $register['uid']]);
 
-       $profile = DBA::selectFirst('profile', ['net-publish'], ['uid' => $register['uid'], 'is-default' => true]);
+       $profile = DBA::selectFirst('profile', ['net-publish'], ['uid' => $register['uid']]);
 
        if (DBA::isResult($profile) && $profile['net-publish'] && DI::config()->get('system', 'directory')) {
                $url = DI::baseUrl() . '/profile/' . $user['nickname'];
index 00991d891988c7fd1f5df4094d773f2f3ab59bb1..3ba5dc2b370ab09cbf6d4110035f80f11319ce75 100644 (file)
@@ -73,9 +73,9 @@ function settings_init(App $a)
        ];
 
        $tabs[] =       [
-               'label' => DI::l10n()->t('Profiles'),
-               'url'   => 'profiles',
-               'selected'      => (($a->argc == 1) && ($a->argv[0] === 'profiles')?'active':''),
+               'label' => DI::l10n()->t('Profile'),
+               'url'   => 'settings/profile',
+               'selected'      => (($a->argc > 1) && ($a->argv[1] === 'profile')?'active':''),
                'accesskey' => 'p',
        ];
 
@@ -611,7 +611,7 @@ function settings_post(App $a)
                `name` = '%s',
                `net-publish` = %d,
                `hide-friends` = %d
-               WHERE `is-default` = 1 AND `uid` = %d",
+               WHERE `uid` = %d",
                intval($publish),
                DBA::escape($username),
                intval($net_publish),
@@ -978,7 +978,7 @@ function settings_content(App $a)
         * ACCOUNT SETTINGS
         */
 
-       $profile = DBA::selectFirst('profile', [], ['is-default' => true, 'uid' => local_user()]);
+       $profile = DBA::selectFirst('profile', [], ['uid' => local_user()]);
        if (!DBA::isResult($profile)) {
                notice(DI::l10n()->t('Unable to find your profile. Please contact your admin.') . EOL);
                return;
diff --git a/mod/update_profile.php b/mod/update_profile.php
deleted file mode 100644 (file)
index 348a384..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-/**
- * Module: update_profile
- * Purpose: AJAX synchronisation of profile page
- */
-
-use Friendica\App;
-use Friendica\DI;
-use Friendica\Module\Profile;
-
-function update_profile_content(App $a) {
-
-       $profile_uid = intval($_GET["p"]);
-
-       header("Content-type: text/html");
-       echo "<!DOCTYPE html><html><body>\r\n";
-
-       // We can remove this hack once Internet Explorer recognises HTML5 natively
-       echo "<section>";
-
-       /**
-        * Grab the page inner contents by calling the content function from the profile module directly,
-        * but move any image src attributes to another attribute name. This is because
-        * some browsers will prefetch all the images for the page even if we don't need them.
-        * The only ones we need to fetch are those for new page additions, which we'll discover
-        * on the client side and then swap the image back.
-        */
-
-       $text = Profile::content([], $profile_uid);
-
-       if (DI::pConfig()->get(local_user(), "system", "bandwidth_saver")) {
-               $replace = "<br />" . DI::l10n()->t("[Embedded content - reload page to view]") . "<br />";
-               $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
-               $text = preg_replace($pattern, $replace, $text);
-               $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
-               $text = preg_replace($pattern, $replace, $text);
-               $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
-               $text = preg_replace($pattern, $replace, $text);
-               $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
-               $text = preg_replace($pattern, $replace, $text);
-       }
-
-       // reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well
-       echo str_replace("\t", "       ", $text);
-       echo "</section>";
-       echo "</body></html>\r\n";
-       exit();
-}
\ No newline at end of file
index a7181d4e78aade725eac94e3b57adfc5d2c75393..36ddef68147bcc1e30dbad6ff6053cd403077996 100644 (file)
@@ -15,6 +15,7 @@ use Friendica\Model\Contact;
 use Friendica\Model\Item;
 use Friendica\Model\Profile;
 use Friendica\Model\User;
+use Friendica\Module\BaseProfile;
 use Friendica\Util\Security;
 
 function videos_init(App $a)
@@ -171,7 +172,7 @@ function videos_content(App $a)
 
        // tabs
        $_is_owner = (local_user() && (local_user() == $owner_uid));
-       $o .= Profile::getTabs($a, 'videos', $_is_owner, $a->data['user']['nickname']);
+       $o .= BaseProfile::getTabsHTML($a, 'videos', $_is_owner, $a->data['user']['nickname']);
 
        //
        // dispatch request
index 4d5803d58524e1b8dccfdba00a9b056c2fccef8a..5a20acee7f4f2a0f1ccf6e34fd6d2a6e03330d64 100644 (file)
@@ -24,7 +24,6 @@ abstract class BaseCollection extends \ArrayIterator
        {
                parent::__construct($models);
 
-               $this->models = $models;
                $this->totalCount = $totalCount ?? count($models);
        }
 
index b2dc7eedaf50ad58b88da114134f2d4671b79852..4e4259170872ea23977c24ef7a425f52b4675575 100644 (file)
@@ -53,6 +53,11 @@ abstract class BaseModel
                return $this->originalData;
        }
 
+       public function resetOriginalData()
+       {
+               $this->originalData = $this->data;
+       }
+
        /**
         * Performance-improved model creation in a loop
         *
index c0bcab18f92fbafc37a8e96b23561eecb1899c66..cce1c50c17bc77f1cdc905a30297b8686f0c7b28 100644 (file)
@@ -122,7 +122,12 @@ abstract class BaseRepository extends BaseFactory
         */
        public function update(BaseModel $model)
        {
-               return $this->dba->update(static::$table_name, $model->toArray(), ['id' => $model->id], $model->getOriginalData());
+               if ($this->dba->update(static::$table_name, $model->toArray(), ['id' => $model->id], $model->getOriginalData())) {
+                       $model->resetOriginalData();
+                       return true;
+               }
+
+               return false;
        }
 
        /**
diff --git a/src/Collection/Notifies.php b/src/Collection/Notifies.php
new file mode 100644 (file)
index 0000000..0d64ee7
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+namespace Friendica\Collection;
+
+use Friendica\BaseCollection;
+use Friendica\Model;
+
+class Notifies extends BaseCollection
+{
+       /**
+        * @return Model\Notify
+        */
+       public function current()
+       {
+               return parent::current();
+       }
+}
diff --git a/src/Collection/ProfileFields.php b/src/Collection/ProfileFields.php
new file mode 100644 (file)
index 0000000..16c2676
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+
+namespace Friendica\Collection;
+
+use Friendica\BaseCollection;
+
+class ProfileFields extends BaseCollection
+{
+       /**
+        * @param callable $callback
+        * @return ProfileFields
+        */
+       public function map(callable $callback)
+       {
+               return parent::map($callback);
+       }
+
+       /**
+        * @param callable|null $callback
+        * @param int           $flag
+        * @return ProfileFields
+        */
+       public function filter(callable $callback = null, int $flag = 0)
+       {
+               return parent::filter($callback, $flag);
+       }
+}
index 0328f063e0e587faa0dbfb7dcea5b674aa118a21..a9c6bc269d9e80d7eac96322a93ec0ddca588022 100644 (file)
@@ -16,33 +16,6 @@ use Friendica\Util\Strings;
  */
 class ContactSelector
 {
-       /**
-        * @param string $current     current
-        * @param string $foreign_net network
-        * @return string
-        * @throws \Exception
-        */
-       public static function profileAssign($current, $foreign_net)
-       {
-               $o = '';
-
-               $disabled = (($foreign_net) ? ' disabled="true" ' : '');
-
-               $o .= "<select id=\"contact-profile-selector\" class=\"form-control\" $disabled name=\"profile-assign\" >\r\n";
-
-               $s = DBA::select('profile', ['id', 'profile-name', 'is-default'], ['uid' => $_SESSION['uid']]);
-               $r = DBA::toArray($s);
-
-               if (DBA::isResult($r)) {
-                       foreach ($r as $rr) {
-                               $selected = (($rr['id'] == $current || ($current == 0 && $rr['is-default'] == 1)) ? " selected=\"selected\" " : "");
-                               $o .= "<option value=\"{$rr['id']}\" $selected >{$rr['profile-name']}</option>\r\n";
-                       }
-               }
-               $o .= "</select>\r\n";
-               return $o;
-       }
-
        /**
         * @param string  $current  current
         * @param boolean $disabled optional, default false
index 91a319677f40cb93fc94ca79e7814d9df571764c..59eea163773563b184186749a83d24752dfb8acf 100644 (file)
@@ -79,7 +79,6 @@ class Feature
                        'general' => [
                                DI::l10n()->t('General Features'),
                                //array('expire',         DI::l10n()->t('Content Expiration'),          DI::l10n()->t('Remove old posts/comments after a period of time')),
-                               ['multi_profiles',  DI::l10n()->t('Multiple Profiles'),      DI::l10n()->t('Ability to create multiple profiles'), false, DI::config()->get('feature_lock', 'multi_profiles', false)],
                                ['photo_location',  DI::l10n()->t('Photo Location'),         DI::l10n()->t("Photo metadata is normally stripped. This extracts the location \x28if present\x29 prior to stripping metadata and links it to a map."), false, DI::config()->get('feature_lock', 'photo_location', false)],
                                ['export_calendar', DI::l10n()->t('Export Public Calendar'), DI::l10n()->t('Ability for visitors to download the public calendar'), false, DI::config()->get('feature_lock', 'export_calendar', false)],
                                ['trending_tags',   DI::l10n()->t('Trending Tags'),          DI::l10n()->t('Show a community page widget with a list of the most popular tags in recent public posts.'), false, DI::config()->get('feature_lock', 'trending_tags', false)],
index 6b4de60361090b27373e4c36aedfe0fd186fae29..3024fcaea1b627478687fcdb2e53275a9a105227 100644 (file)
@@ -258,10 +258,6 @@ class Nav
 
                        $nav['settings'] = ['settings', DI::l10n()->t('Settings'), '', DI::l10n()->t('Account settings')];
 
-                       if (Feature::isEnabled(local_user(), 'multi_profiles')) {
-                               $nav['profiles'] = ['profiles', DI::l10n()->t('Profiles'), '', DI::l10n()->t('Manage/Edit Profiles')];
-                       }
-
                        $nav['contacts'] = ['contact', DI::l10n()->t('Contacts'), '', DI::l10n()->t('Manage/edit friends and contacts')];
                }
 
index 8fa09ee8a25cf63da6d2f3719a0b751c5dfef3fb..c3ec88fc914e576345d57d95eea964b6dac79726 100644 (file)
@@ -13,6 +13,7 @@ use Friendica\DI;
 use Friendica\Model\Contact;
 use Friendica\Model\FileTag;
 use Friendica\Model\GContact;
+use Friendica\Model\Group;
 use Friendica\Model\Item;
 use Friendica\Model\Profile;
 use Friendica\Util\DateTimeFormat;
@@ -82,7 +83,7 @@ class Widget
        public static function unavailableNetworks()
        {
                // Always hide content from these networks
-               $networks = ['face', 'apdn'];
+               $networks = [Protocol::PHANTOM, Protocol::FACEBOOK, Protocol::APPNET];
 
                if (!Addon::isEnabled("discourse")) {
                        $networks[] = Protocol::DISCOURSE;
@@ -175,7 +176,39 @@ class Widget
        }
 
        /**
-        * Return networks widget
+        * Return group membership widget
+        *
+        * @param string $baseurl
+        * @param string $selected
+        * @return string
+        * @throws \Exception
+        */
+       public static function groups($baseurl, $selected = '')
+       {
+               if (!local_user()) {
+                       return '';
+               }
+
+               $options = array_map(function ($group) {
+                       return [
+                               'ref'  => $group['id'],
+                               'name' => $group['name']
+                       ];
+               }, Group::getByUserId(local_user()));
+
+               return self::filter(
+                       'group',
+                       DI::l10n()->t('Groups'),
+                       '',
+                       DI::l10n()->t('Everyone'),
+                       $baseurl,
+                       $options,
+                       $selected
+               );
+       }
+
+       /**
+        * Return contact relationship widget
         *
         * @param string $baseurl  baseurl
         * @param string $selected optional, default empty
index c77674127af5b55e5f161f77f512b5a64b81be1d..f09db9868667198e63d1f8496ecadc7f738ae5a4 100644 (file)
@@ -8,8 +8,10 @@ use Friendica\App;
 use Friendica\Database\DBA;
 use Friendica\Database\DBStructure;
 use Friendica\DI;
+use Friendica\Model\Contact;
 use Friendica\Model\Photo;
 use Friendica\Object\Image;
+use Friendica\Repository\PermissionSet;
 use Friendica\Util\Strings;
 use Friendica\Worker\Delivery;
 
@@ -161,23 +163,6 @@ class UserImport
 
                DI::pConfig()->set($newuid, 'system', 'previous_addr', $old_handle);
 
-               foreach ($account['profile'] as &$profile) {
-                       foreach ($profile as $k => &$v) {
-                               $v = str_replace([$oldbaseurl, $oldaddr], [$newbaseurl, $newaddr], $v);
-                               foreach (["profile", "avatar"] as $k) {
-                                       $v = str_replace($oldbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v);
-                               }
-                       }
-                       $profile['uid'] = $newuid;
-                       $r = self::dbImportAssoc('profile', $profile);
-                       if ($r === false) {
-                               Logger::log("uimport:insert profile " . $profile['profile-name'] . " : ERROR : " . DBA::errorMessage(), Logger::INFO);
-                               info(DI::l10n()->t("User profile creation error"));
-                               DBA::delete('user', ['uid' => $newuid]);
-                               return;
-                       }
-               }
-
                $errorcount = 0;
                foreach ($account['contact'] as &$contact) {
                        if ($contact['uid'] == $olduid && $contact['self'] == '1') {
@@ -253,6 +238,50 @@ class UserImport
                        }
                }
 
+               foreach ($account['profile'] as &$profile) {
+                       unset($profile['id']);
+                       $profile['uid'] = $newuid;
+
+                       foreach ($profile as $k => &$v) {
+                               $v = str_replace([$oldbaseurl, $oldaddr], [$newbaseurl, $newaddr], $v);
+                               foreach (["profile", "avatar"] as $k) {
+                                       $v = str_replace($oldbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v);
+                               }
+                       }
+
+                       if (count($account['profile']) === 1 || $profile['is-default']) {
+                               $r = self::dbImportAssoc('profile', $profile);
+
+                               if ($r === false) {
+                                       Logger::log("uimport:insert profile: ERROR : " . DBA::errorMessage(), Logger::INFO);
+                                       info(DI::l10n()->t("User profile creation error"));
+                                       DBA::delete('user', ['uid' => $newuid]);
+                                       DBA::delete('profile_field', ['uid' => $newuid]);
+                                       return;
+                               }
+
+                               $profile['id'] = DBA::lastInsertId();
+                       }
+
+                       DI::profileField()->migrateFromLegacyProfile($profile);
+               }
+
+               ///@TODO Replace with permissionset import
+               $self_contact = Contact::selectFirst(['id'], ['uid' => $newuid, 'self' => true]);
+               $allow_cid = DI::aclFormatter()->toString($self_contact['id']);
+               $self_psid = DI::permissionSet()->getIdFromACL($newuid, $allow_cid);
+
+               foreach ($account['profile_fields'] ?? [] as $profile_field) {
+                       $profile_field['uid'] = $newuid;
+
+                       ///@TODO Replace with permissionset import
+                       $profile_field['psid'] = $profile_field['psid'] ? $self_psid : PermissionSet::PUBLIC;
+
+                       if (self::dbImportAssoc('profile_field', $profile_field) === false) {
+                               Logger::info("uimport:insert profile field " . $profile_field['id'] . " : ERROR : " . DBA::errorMessage());
+                       }
+               }
+
                foreach ($account['photo'] as &$photo) {
                        $photo['uid'] = $newuid;
                        $photo['data'] = hex2bin($photo['data']);
index e6d9c341b7ed42a826734686df9c550611b652c7..6eb1ed4b633c17d73c2f67cef8495f5063cdd8c4 100644 (file)
@@ -244,6 +244,22 @@ abstract class DI
                return self::$dice->create(Factory\Mastodon\Relationship::class);
        }
 
+       /**
+        * @return \Friendica\Factory\Notification\Notification
+        */
+       public static function notification()
+       {
+               return self::$dice->create(Factory\Notification\Notification::class);
+       }
+
+       /**
+        * @return \Friendica\Factory\Notification\Introduction
+        */
+       public static function notificationIntro()
+       {
+               return self::$dice->create(Factory\Notification\Introduction::class);
+       }
+
        //
        // "Model" namespace instances
        //
@@ -257,11 +273,11 @@ abstract class DI
        }
 
        /**
-        * @return Model\Notify
+        * @return Repository\Notify
         */
        public static function notify()
        {
-               return self::$dice->create(Model\Notify::class);
+               return self::$dice->create(Repository\Notify::class);
        }
 
        /**
@@ -292,6 +308,14 @@ abstract class DI
                return self::$dice->create(Repository\PermissionSet::class);
        }
 
+       /**
+        * @return Repository\ProfileField
+        */
+       public static function profileField()
+       {
+               return self::$dice->create(Repository\ProfileField::class);
+       }
+
        //
        // "Protocol" namespace instances
        //
@@ -339,4 +363,12 @@ abstract class DI
        {
                return self::$dice->create(Util\Profiler::class);
        }
+
+       /**
+        * @return Util\Emailer
+        */
+       public static function emailer()
+       {
+               return self::$dice->create(Util\Emailer::class);
+       }
 }
diff --git a/src/Factory/Notification/Introduction.php b/src/Factory/Notification/Introduction.php
new file mode 100644 (file)
index 0000000..7546792
--- /dev/null
@@ -0,0 +1,211 @@
+<?php
+
+namespace Friendica\Factory\Notification;
+
+use Exception;
+use Friendica\App;
+use Friendica\App\BaseURL;
+use Friendica\BaseFactory;
+use Friendica\Content\Text\BBCode;
+use Friendica\Core\L10n;
+use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\Protocol;
+use Friendica\Core\Session\ISession;
+use Friendica\Database\Database;
+use Friendica\Model\Contact;
+use Friendica\Module\BaseNotifications;
+use Friendica\Network\HTTPException\InternalServerErrorException;
+use Friendica\Object\Notification;
+use Friendica\Util\Proxy;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Factory for creating notification objects based on introductions
+ * Currently, there are two main types of introduction based notifications:
+ * - Friend suggestion
+ * - Friend/Follower request
+ */
+class Introduction extends BaseFactory
+{
+       /** @var Database */
+       private $dba;
+       /** @var BaseURL */
+       private $baseUrl;
+       /** @var L10n */
+       private $l10n;
+       /** @var IPConfig */
+       private $pConfig;
+       /** @var ISession */
+       private $session;
+       /** @var string */
+       private $nick;
+
+       public function __construct(LoggerInterface $logger, Database $dba, BaseURL $baseUrl, L10n $l10n, App $app, IPConfig $pConfig, ISession $session)
+       {
+               parent::__construct($logger);
+
+               $this->dba          = $dba;
+               $this->baseUrl      = $baseUrl;
+               $this->l10n         = $l10n;
+               $this->pConfig      = $pConfig;
+               $this->session      = $session;
+               $this->nick         = $app->user['nickname'] ?? '';
+       }
+
+       /**
+        * Get introductions
+        *
+        * @param bool $all     If false only include introductions into the query
+        *                      which aren't marked as ignored
+        * @param int  $start   Start the query at this point
+        * @param int  $limit   Maximum number of query results
+        * @param int  $id      When set, only the introduction with this id is displayed
+        *
+        * @return Notification\Introduction[]
+        */
+       public function getList(bool $all = false, int $start = 0, int $limit = BaseNotifications::DEFAULT_PAGE_LIMIT, int $id = 0)
+       {
+               $sql_extra     = "";
+
+               if (empty($id)) {
+                       if (!$all) {
+                               $sql_extra = " AND NOT `ignore` ";
+                       }
+
+                       $sql_extra .= " AND NOT `intro`.`blocked` ";
+               } else {
+                       $sql_extra = sprintf(" AND `intro`.`id` = %d ", intval($id));
+               }
+
+               $formattedNotifications = [];
+
+               try {
+                       /// @todo Fetch contact details by "Contact::getDetailsByUrl" instead of queries to contact, fcontact and gcontact
+                       $stmtNotifications = $this->dba->p(
+                               "SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*,
+                               `fcontact`.`name` AS `fname`, `fcontact`.`url` AS `furl`, `fcontact`.`addr` AS `faddr`,
+                               `fcontact`.`photo` AS `fphoto`, `fcontact`.`request` AS `frequest`,
+                               `gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`,
+                               `gcontact`.`keywords` AS `gkeywords`, `gcontact`.`gender` AS `ggender`,
+                               `gcontact`.`network` AS `gnetwork`, `gcontact`.`addr` AS `gaddr`
+                       FROM `intro`
+                               LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
+                               LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
+                               LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
+                       WHERE `intro`.`uid` = ? $sql_extra
+                       LIMIT ?, ?",
+                               $_SESSION['uid'],
+                               $start,
+                               $limit
+                       );
+
+                       while ($notification = $this->dba->fetch($stmtNotifications)) {
+                               // There are two kind of introduction. Contacts suggested by other contacts and normal connection requests.
+                               // We have to distinguish between these two because they use different data.
+                               // Contact suggestions
+                               if ($notification['fid'] ?? '') {
+                                       $return_addr = bin2hex($this->nick . '@' .
+                                                              $this->baseUrl->getHostName() .
+                                                              (($this->baseUrl->getURLPath()) ? '/' . $this->baseUrl->getURLPath() : ''));
+
+                                       $formattedNotifications[] = new Notification\Introduction([
+                                               'label'          => 'friend_suggestion',
+                                               'str_type'       => $this->l10n->t('Friend Suggestion'),
+                                               'intro_id'       => $notification['intro_id'],
+                                               'madeby'         => $notification['name'],
+                                               'madeby_url'     => $notification['url'],
+                                               'madeby_zrl'     => Contact::magicLink($notification['url']),
+                                               'madeby_addr'    => $notification['addr'],
+                                               'contact_id'     => $notification['contact-id'],
+                                               'photo'          => (!empty($notification['fphoto']) ? Proxy::proxifyUrl($notification['fphoto'], false, Proxy::SIZE_SMALL) : "images/person-300.jpg"),
+                                               'name'           => $notification['fname'],
+                                               'url'            => $notification['furl'],
+                                               'zrl'            => Contact::magicLink($notification['furl']),
+                                               'hidden'         => $notification['hidden'] == 1,
+                                               'post_newfriend' => (intval($this->pConfig->get(local_user(), 'system', 'post_newfriend')) ? '1' : 0),
+                                               'note'           => $notification['note'],
+                                               'request'        => $notification['frequest'] . '?addr=' . $return_addr]);
+
+                                       // Normal connection requests
+                               } else {
+                                       $notification = $this->getMissingData($notification);
+
+                                       if (empty($notification['url'])) {
+                                               continue;
+                                       }
+
+                                       // Don't show these data until you are connected. Diaspora is doing the same.
+                                       if ($notification['gnetwork'] === Protocol::DIASPORA) {
+                                               $notification['glocation'] = "";
+                                               $notification['gabout']    = "";
+                                               $notification['ggender']   = "";
+                                       }
+
+                                       $formattedNotifications[] = new Notification\Introduction([
+                                               'label'          => (($notification['network'] !== Protocol::OSTATUS) ? 'friend_request' : 'follower'),
+                                               'str_type'       => (($notification['network'] !== Protocol::OSTATUS) ? $this->l10n->t('Friend/Connect Request') : $this->l10n->t('New Follower')),
+                                               'dfrn_id'        => $notification['issued-id'],
+                                               'uid'            => $this->session->get('uid'),
+                                               'intro_id'       => $notification['intro_id'],
+                                               'contact_id'     => $notification['contact-id'],
+                                               'photo'          => (!empty($notification['photo']) ? Proxy::proxifyUrl($notification['photo'], false, Proxy::SIZE_SMALL) : "images/person-300.jpg"),
+                                               'name'           => $notification['name'],
+                                               'location'       => BBCode::convert($notification['glocation'], false),
+                                               'about'          => BBCode::convert($notification['gabout'], false),
+                                               'keywords'       => $notification['gkeywords'],
+                                               'gender'         => $notification['ggender'],
+                                               'hidden'         => $notification['hidden'] == 1,
+                                               'post_newfriend' => (intval($this->pConfig->get(local_user(), 'system', 'post_newfriend')) ? '1' : 0),
+                                               'url'            => $notification['url'],
+                                               'zrl'            => Contact::magicLink($notification['url']),
+                                               'addr'           => $notification['gaddr'],
+                                               'network'        => $notification['gnetwork'],
+                                               'knowyou'        => $notification['knowyou'],
+                                               'note'           => $notification['note'],
+                                       ]);
+                               }
+                       }
+               } catch (Exception $e) {
+                       $this->logger->warning('Select failed.', ['uid' => $_SESSION['uid'], 'exception' => $e]);
+               }
+
+               return $formattedNotifications;
+       }
+
+       /**
+        * Check for missing contact data and try to fetch the data from
+        * from other sources
+        *
+        * @param array $intro The input array with the intro data
+        *
+        * @return array The array with the intro data
+        *
+        * @throws InternalServerErrorException
+        */
+       private function getMissingData(array $intro)
+       {
+               // If the network and the addr isn't available from the gcontact
+               // table entry, take the one of the contact table entry
+               if (empty($intro['gnetwork']) && !empty($intro['network'])) {
+                       $intro['gnetwork'] = $intro['network'];
+               }
+               if (empty($intro['gaddr']) && !empty($intro['addr'])) {
+                       $intro['gaddr'] = $intro['addr'];
+               }
+
+               // If the network and addr is still not available
+               // get the missing data data from other sources
+               if (empty($intro['gnetwork']) || empty($intro['gaddr'])) {
+                       $ret = Contact::getDetailsByURL($intro['url']);
+
+                       if (empty($intro['gnetwork']) && !empty($ret['network'])) {
+                               $intro['gnetwork'] = $ret['network'];
+                       }
+                       if (empty($intro['gaddr']) && !empty($ret['addr'])) {
+                               $intro['gaddr'] = $ret['addr'];
+                       }
+               }
+
+               return $intro;
+       }
+}
diff --git a/src/Factory/Notification/Notification.php b/src/Factory/Notification/Notification.php
new file mode 100644 (file)
index 0000000..5f2c223
--- /dev/null
@@ -0,0 +1,355 @@
+<?php
+
+namespace Friendica\Factory\Notification;
+
+use Exception;
+use Friendica\App;
+use Friendica\App\BaseURL;
+use Friendica\BaseFactory;
+use Friendica\Content\Text\BBCode;
+use Friendica\Core\L10n;
+use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\Protocol;
+use Friendica\Core\Session\ISession;
+use Friendica\Database\Database;
+use Friendica\Model\Item;
+use Friendica\Module\BaseNotifications;
+use Friendica\Network\HTTPException\InternalServerErrorException;
+use Friendica\Protocol\Activity;
+use Friendica\Repository;
+use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Proxy;
+use Friendica\Util\Temporal;
+use Friendica\Util\XML;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Factory for creating notification objects based on items
+ * Currently, there are the following types of item based notifications:
+ * - network
+ * - system
+ * - home
+ * - personal
+ */
+class Notification extends BaseFactory
+{
+       /** @var Database */
+       private $dba;
+       /** @var Repository\Notify */
+       private $notification;
+       /** @var BaseURL */
+       private $baseUrl;
+       /** @var L10n */
+       private $l10n;
+       /** @var string */
+       private $nurl;
+
+       public function __construct(LoggerInterface $logger, Database $dba, Repository\Notify $notification, BaseURL $baseUrl, L10n $l10n, App $app, IPConfig $pConfig, ISession $session)
+       {
+               parent::__construct($logger);
+
+               $this->dba          = $dba;
+               $this->notification = $notification;
+               $this->baseUrl      = $baseUrl;
+               $this->l10n         = $l10n;
+               $this->nurl         = $app->contact['nurl'] ?? '';
+       }
+
+       /**
+        * Format the item query in an usable array
+        *
+        * @param array $item The item from the db query
+        *
+        * @return array The item, extended with the notification-specific information
+        *
+        * @throws InternalServerErrorException
+        * @throws Exception
+        */
+       private function formatItem(array $item)
+       {
+               $item['seen'] = ($item['unseen'] > 0 ? false : true);
+
+               // For feed items we use the user's contact, since the avatar is mostly self choosen.
+               if (!empty($item['network']) && $item['network'] == Protocol::FEED) {
+                       $item['author-avatar'] = $item['contact-avatar'];
+               }
+
+               $item['label'] = (($item['id'] == $item['parent']) ? 'post' : 'comment');
+               $item['link']  = $this->baseUrl->get(true) . '/display/' . $item['parent-guid'];
+               $item['image'] = Proxy::proxifyUrl($item['author-avatar'], false, Proxy::SIZE_MICRO);
+               $item['url']   = $item['author-link'];
+               $item['text']  = (($item['id'] == $item['parent'])
+                       ? $this->l10n->t("%s created a new post", $item['author-name'])
+                       : $this->l10n->t("%s commented on %s's post", $item['author-name'], $item['parent-author-name']));
+               $item['when']  = DateTimeFormat::local($item['created'], 'r');
+               $item['ago']   = Temporal::getRelativeDate($item['created']);
+
+               return $item;
+       }
+
+       /**
+        * @param array $item
+        *
+        * @return \Friendica\Object\Notification\Notification
+        *
+        * @throws InternalServerErrorException
+        */
+       private function createFromItem(array $item)
+       {
+               $item = $this->formatItem($item);
+
+               // Transform the different types of notification in an usable array
+               switch ($item['verb'] ?? '') {
+                       case Activity::LIKE:
+                               return new \Friendica\Object\Notification\Notification([
+                                       'label' => 'like',
+                                       'link'  => $this->baseUrl->get(true) . '/display/' . $item['parent-guid'],
+                                       'image' => Proxy::proxifyUrl($item['author-avatar'], false, Proxy::SIZE_MICRO),
+                                       'url'   => $item['author-link'],
+                                       'text'  => $this->l10n->t("%s liked %s's post", $item['author-name'], $item['parent-author-name']),
+                                       'when'  => $item['when'],
+                                       'ago'   => $item['ago'],
+                                       'seen'  => $item['seen']]);
+
+                       case Activity::DISLIKE:
+                               return new \Friendica\Object\Notification\Notification([
+                                       'label' => 'dislike',
+                                       'link'  => $this->baseUrl->get(true) . '/display/' . $item['parent-guid'],
+                                       'image' => Proxy::proxifyUrl($item['author-avatar'], false, Proxy::SIZE_MICRO),
+                                       'url'   => $item['author-link'],
+                                       'text'  => $this->l10n->t("%s disliked %s's post", $item['author-name'], $item['parent-author-name']),
+                                       'when'  => $item['when'],
+                                       'ago'   => $item['ago'],
+                                       'seen'  => $item['seen']]);
+
+                       case Activity::ATTEND:
+                               return new \Friendica\Object\Notification\Notification([
+                                       'label' => 'attend',
+                                       'link'  => $this->baseUrl->get(true) . '/display/' . $item['parent-guid'],
+                                       'image' => Proxy::proxifyUrl($item['author-avatar'], false, Proxy::SIZE_MICRO),
+                                       'url'   => $item['author-link'],
+                                       'text'  => $this->l10n->t("%s is attending %s's event", $item['author-name'], $item['parent-author-name']),
+                                       'when'  => $item['when'],
+                                       'ago'   => $item['ago'],
+                                       'seen'  => $item['seen']]);
+
+                       case Activity::ATTENDNO:
+                               return new \Friendica\Object\Notification\Notification([
+                                       'label' => 'attendno',
+                                       'link'  => $this->baseUrl->get(true) . '/display/' . $item['parent-guid'],
+                                       'image' => Proxy::proxifyUrl($item['author-avatar'], false, Proxy::SIZE_MICRO),
+                                       'url'   => $item['author-link'],
+                                       'text'  => $this->l10n->t("%s is not attending %s's event", $item['author-name'], $item['parent-author-name']),
+                                       'when'  => $item['when'],
+                                       'ago'   => $item['ago'],
+                                       'seen'  => $item['seen']]);
+
+                       case Activity::ATTENDMAYBE:
+                               return new \Friendica\Object\Notification\Notification([
+                                       'label' => 'attendmaybe',
+                                       'link'  => $this->baseUrl->get(true) . '/display/' . $item['parent-guid'],
+                                       'image' => Proxy::proxifyUrl($item['author-avatar'], false, Proxy::SIZE_MICRO),
+                                       'url'   => $item['author-link'],
+                                       'text'  => $this->l10n->t("%s may attending %s's event", $item['author-name'], $item['parent-author-name']),
+                                       'when'  => $item['when'],
+                                       'ago'   => $item['ago'],
+                                       'seen'  => $item['seen']]);
+
+                       case Activity::FRIEND:
+                               if (!isset($item['object'])) {
+                                       return new \Friendica\Object\Notification\Notification([
+                                               'label' => 'friend',
+                                               'link'  => $item['link'],
+                                               'image' => $item['image'],
+                                               'url'   => $item['url'],
+                                               'text'  => $item['text'],
+                                               'when'  => $item['when'],
+                                               'ago'   => $item['ago'],
+                                               'seen'  => $item['seen']]);
+                               }
+
+                               $xmlHead       = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">";
+                               $obj           = XML::parseString($xmlHead . $item['object']);
+                               $item['fname'] = $obj->title;
+
+                               return new \Friendica\Object\Notification\Notification([
+                                       'label' => 'friend',
+                                       'link'  => $this->baseUrl->get(true) . '/display/' . $item['parent-guid'],
+                                       'image' => Proxy::proxifyUrl($item['author-avatar'], false, Proxy::SIZE_MICRO),
+                                       'url'   => $item['author-link'],
+                                       'text'  => $this->l10n->t("%s is now friends with %s", $item['author-name'], $item['fname']),
+                                       'when'  => $item['when'],
+                                       'ago'   => $item['ago'],
+                                       'seen'  => $item['seen']]);
+
+                       default:
+                               return new \Friendica\Object\Notification\Notification($item);
+                               break;
+               }
+       }
+
+       /**
+        * Get system notifications
+        *
+        * @param bool $seen          False => only include notifications into the query
+        *                            which aren't marked as "seen"
+        * @param int  $start         Start the query at this point
+        * @param int  $limit         Maximum number of query results
+        *
+        * @return \Friendica\Module\Notifications\Notification[]
+        */
+       public function getSystemList(bool $seen = false, int $start = 0, int $limit = BaseNotifications::DEFAULT_PAGE_LIMIT)
+       {
+               $conditions = ['uid' => local_user()];
+
+               if (!$seen) {
+                       $conditions['seen'] = false;
+               }
+
+               $params          = [];
+               $params['order'] = ['date' => 'DESC'];
+               $params['limit'] = [$start, $limit];
+
+               $formattedNotifications = [];
+               try {
+                       $notifications = $this->notification->select($conditions, $params);
+
+                       foreach ($notifications as $notification) {
+                               $formattedNotifications[] = new \Friendica\Object\Notification\Notification([
+                                       'label' => 'notification',
+                                       'link'  => $this->baseUrl->get(true) . '/notification/view/' . $notification->id,
+                                       'image' => Proxy::proxifyUrl($notification->photo, false, Proxy::SIZE_MICRO),
+                                       'url'   => $notification->url,
+                                       'text'  => strip_tags(BBCode::convert($notification->msg)),
+                                       'when'  => DateTimeFormat::local($notification->date, 'r'),
+                                       'ago'   => Temporal::getRelativeDate($notification->date),
+                                       'seen'  => $notification->seen]);
+                       }
+               } catch (Exception $e) {
+                       $this->logger->warning('Select failed.', ['conditions' => $conditions, 'exception' => $e]);
+               }
+
+               return $formattedNotifications;
+       }
+
+       /**
+        * Get network notifications
+        *
+        * @param bool $seen          False => only include notifications into the query
+        *                            which aren't marked as "seen"
+        * @param int  $start         Start the query at this point
+        * @param int  $limit         Maximum number of query results
+        *
+        * @return \Friendica\Object\Notification\Notification[]
+        */
+       public function getNetworkList(bool $seen = false, int $start = 0, int $limit = BaseNotifications::DEFAULT_PAGE_LIMIT)
+       {
+               $conditions = ['wall' => false, 'uid' => local_user()];
+
+               if (!$seen) {
+                       $conditions['unseen'] = true;
+               }
+
+               $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
+                       'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
+               $params = ['order' => ['received' => true], 'limit' => [$start, $limit]];
+
+               $formattedNotifications = [];
+
+               try {
+                       $items = Item::selectForUser(local_user(), $fields, $conditions, $params);
+
+                       while ($item = $this->dba->fetch($items)) {
+                               $formattedNotifications[] = $this->createFromItem($item);
+                       }
+               } catch (Exception $e) {
+                       $this->logger->warning('Select failed.', ['conditions' => $conditions, 'exception' => $e]);
+               }
+
+               return $formattedNotifications;
+       }
+
+       /**
+        * Get personal notifications
+        *
+        * @param bool $seen          False => only include notifications into the query
+        *                            which aren't marked as "seen"
+        * @param int  $start         Start the query at this point
+        * @param int  $limit         Maximum number of query results
+        *
+        * @return \Friendica\Object\Notification\Notification[]
+        */
+       public function getPersonalList(bool $seen = false, int $start = 0, int $limit = BaseNotifications::DEFAULT_PAGE_LIMIT)
+       {
+               $myUrl    = str_replace('http://', '', $this->nurl);
+               $diaspUrl = str_replace('/profile/', '/u/', $myUrl);
+
+               $condition = ["NOT `wall` AND `uid` = ? AND (`item`.`author-id` = ? OR `item`.`tag` REGEXP ? OR `item`.`tag` REGEXP ?)",
+                       local_user(), public_contact(), $myUrl . '\\]', $diaspUrl . '\\]'];
+
+               if (!$seen) {
+                       $condition[0] .= " AND `unseen`";
+               }
+
+               $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
+                       'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
+               $params = ['order' => ['received' => true], 'limit' => [$start, $limit]];
+
+               $formattedNotifications = [];
+
+               try {
+                       $items = Item::selectForUser(local_user(), $fields, $condition, $params);
+
+                       while ($item = $this->dba->fetch($items)) {
+                               $formattedNotifications[] = $this->createFromItem($item);
+                       }
+               } catch (Exception $e) {
+                       $this->logger->warning('Select failed.', ['conditions' => $condition, 'exception' => $e]);
+               }
+
+               return $formattedNotifications;
+       }
+
+       /**
+        * Get home notifications
+        *
+        * @param bool $seen          False => only include notifications into the query
+        *                            which aren't marked as "seen"
+        * @param int  $start         Start the query at this point
+        * @param int  $limit         Maximum number of query results
+        *
+        * @return \Friendica\Object\Notification\Notification[]
+        */
+       public function getHomeList(bool $seen = false, int $start = 0, int $limit = BaseNotifications::DEFAULT_PAGE_LIMIT)
+       {
+               $condition = ['wall' => true, 'uid' => local_user()];
+
+               if (!$seen) {
+                       $condition['unseen'] = true;
+               }
+
+               $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
+                       'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
+               $params = ['order' => ['received' => true], 'limit' => [$start, $limit]];
+
+               $formattedNotifications = [];
+
+               try {
+                       $items = Item::selectForUser(local_user(), $fields, $condition, $params);
+
+                       while ($item = $this->dba->fetch($items)) {
+                               $item = $this->formatItem($item);
+
+                               // Overwrite specific fields, not default item format
+                               $item['label'] = 'comment';
+                               $item['text']  = $this->l10n->t("%s commented on %s's post", $item['author-name'], $item['parent-author-name']);
+
+                               $formattedNotifications[] = $this->createFromItem($item);
+                       }
+               } catch (Exception $e) {
+                       $this->logger->warning('Select failed.', ['conditions' => $condition, 'exception' => $e]);
+               }
+
+               return $formattedNotifications;
+       }
+}
index 08c67f8efadd0f327011839583134cf673d0ea9a..d20872ed64376c8df855c6917430ba0890920057 100644 (file)
@@ -723,7 +723,7 @@ class Contact
 
                $fields = ['name', 'photo', 'thumb', 'about', 'address', 'locality', 'region',
                        'country-name', 'gender', 'pub_keywords', 'xmpp', 'net-publish'];
-               $profile = DBA::selectFirst('profile', $fields, ['uid' => $uid, 'is-default' => true]);
+               $profile = DBA::selectFirst('profile', $fields, ['uid' => $uid]);
                if (!DBA::isResult($profile)) {
                        return;
                }
@@ -800,7 +800,7 @@ class Contact
                        // Update the profile
                        $fields = ['photo' => DI::baseUrl() . '/photo/profile/' .$uid . '.' . $file_suffix,
                                'thumb' => DI::baseUrl() . '/photo/avatar/' . $uid .'.' . $file_suffix];
-                       DBA::update('profile', $fields, ['uid' => $uid, 'is-default' => true]);
+                       DBA::update('profile', $fields, ['uid' => $uid]);
                }
        }
 
index 7e8a71c16560f00af8acc72b41a6e43f730ebc2e..1bb9f29047a701d0297fea225b4fbcf4efa261de 100644 (file)
 namespace Friendica\Model;
 
 use Exception;
-use Friendica\App;
+use Friendica\BaseModel;
 use Friendica\Content\Text\BBCode;
 use Friendica\Content\Text\HTML;
-use Friendica\Core\PConfig\IPConfig;
-use Friendica\Core\L10n;
-use Friendica\Core\Protocol;
-use Friendica\Core\System;
 use Friendica\Database\Database;
-use Friendica\DI;
-use Friendica\Protocol\Activity;
+use Friendica\Network\HTTPException\InternalServerErrorException;
 use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Proxy as ProxyUtils;
 use Friendica\Util\Temporal;
-use Friendica\Util\XML;
-use ImagickException;
 use Psr\Log\LoggerInterface;
-use Friendica\Network\HTTPException;
 
 /**
- * Methods for read and write notifications from/to database
- *  or for formatting notifications
+ * Model for an entry in the notify table
+ * - Including additional, calculated properties
+ *
+ * Is used either for frontend interactions or for API-based interaction
+ * @see https://github.com/friendica/friendica/blob/develop/doc/API-Entities.md#notification
+ *
+ * @property string  hash
+ * @property integer type
+ * @property string  name   Full name of the contact subject
+ * @property string  url    Profile page URL of the contact subject
+ * @property string  photo  Profile photo URL of the contact subject
+ * @property string  date   YYYY-MM-DD hh:mm:ss local server time
+ * @property string  msg
+ * @property integer uid       Owner User Id
+ * @property string  link   Notification URL
+ * @property integer iid       Item Id
+ * @property integer parent Parent Item Id
+ * @property boolean seen   Whether the notification was read or not.
+ * @property string  verb   Verb URL (@see http://activitystrea.ms)
+ * @property string  otype  Subject type (`item`, `intro` or `mail`)
+ *
+ * @property-read string name_cache Full name of the contact subject
+ * @property-read string msg_cache  Plaintext version of the notification text with a placeholder (`{0}`) for the subject contact's name.
+ *
+ * @property-read integer timestamp  Unix timestamp
+ * @property-read string  dateRel       Time since the note was posted, eg "1 hour ago"
+ * @property-read string  $msg_html
+ * @property-read string  $msg_plain
  */
-final class Notify
+class Notify extends BaseModel
 {
-       /** @var int The default limit of notifies per page */
-       const DEFAULT_PAGE_LIMIT = 80;
+       const OTYPE_ITEM   = 'item';
+       const OTYPE_INTRO  = 'intro';
+       const OTYPE_MAIL   = 'mail';
+       const OTYPE_PERSON = 'person';
 
-       const NETWORK  = 'network';
-       const SYSTEM   = 'system';
-       const PERSONAL = 'personal';
-       const HOME     = 'home';
-       const INTRO    = 'intro';
+       /** @var \Friendica\Repository\Notify */
+       private $repo;
 
-       /** @var Database */
-       private $dba;
-       /** @var L10n */
-       private $l10n;
-       /** @var App\Arguments */
-       private $args;
-       /** @var App\BaseURL */
-       private $baseUrl;
-       /** @var IPConfig */
-       private $pConfig;
-       /** @var LoggerInterface */
-       private $logger;
-
-       public function __construct(Database $dba, L10n $l10n, App\Arguments $args, App\BaseURL $baseUrl,
-                                   IPConfig $pConfig, LoggerInterface $logger)
+       public function __construct(Database $dba, LoggerInterface $logger, \Friendica\Repository\Notify $repo, array $data = [])
        {
-               $this->dba     = $dba;
-               $this->l10n    = $l10n;
-               $this->args    = $args;
-               $this->baseUrl = $baseUrl;
-               $this->pConfig = $pConfig;
-               $this->logger  = $logger;
-       }
+               parent::__construct($dba, $logger, $data);
 
-       /**
-        * Set some extra properties to note array from db:
-        *  - timestamp as int in default TZ
-        *  - date_rel : relative date string
-        *  - msg_html: message as html string
-        *  - msg_plain: message as plain text string
-        *
-        * @param array $notes array of note arrays from db
-        *
-        * @return array Copy of input array with added properties
-        *
-        * @throws Exception
-        */
-       private function setExtra(array $notes)
-       {
-               $retNotes = [];
-               foreach ($notes as $note) {
-                       $local_time        = DateTimeFormat::local($note['date']);
-                       $note['timestamp'] = strtotime($local_time);
-                       $note['date_rel']  = Temporal::getRelativeDate($note['date']);
-                       $note['msg_html']  = BBCode::convert($note['msg'], false);
-                       $note['msg_plain'] = explode("\n", trim(HTML::toPlaintext($note['msg_html'], 0)))[0];
+               $this->repo = $repo;
 
-                       $retNotes[] = $note;
-               }
-               return $retNotes;
+               $this->setNameCache();
+               $this->setTimestamp();
+               $this->setMsg();
        }
 
        /**
-        * Get all notifications for local_user()
+        * Set the notification as seen
         *
-        * @param array  $filter optional Array "column name"=>value: filter query by columns values
-        * @param array  $order  optional Array to order by
-        * @param string $limit  optional Query limits
+        * @param bool $seen true, if seen
         *
-        * @return array|bool of results or false on errors
-        * @throws Exception
+        * @return bool True, if the seen state could be saved
         */
-       public function getAll(array $filter = [], array $order = ['date' => 'DESC'], string $limit = "")
+       public function setSeen(bool $seen = true)
        {
-               $params = [];
-
-               $params['order'] = $order;
-
-               if (!empty($limit)) {
-                       $params['limit'] = $limit;
-               }
-
-               $dbFilter = array_merge($filter, ['uid' => local_user()]);
-
-               $stmtNotifies = $this->dba->select('notify', [], $dbFilter, $params);
-
-               if ($this->dba->isResult($stmtNotifies)) {
-                       return $this->setExtra($this->dba->toArray($stmtNotifies));
+               $this->seen = $seen;
+               try {
+                       return $this->repo->update($this);
+               } catch (Exception $e) {
+                       $this->logger->warning('Update failed.', ['$this' => $this, 'exception' => $e]);
+                       return false;
                }
-
-               return false;
        }
 
        /**
-        * Get one note for local_user() by $id value
-        *
-        * @param int $id identity
-        *
-        * @return array note values or null if not found
-        * @throws Exception
+        * Set some extra properties to the notification from db:
+        *  - timestamp as int in default TZ
+        *  - date_rel : relative date string
         */
-       public function getByID(int $id)
+       private function setTimestamp()
        {
-               $stmtNotify = $this->dba->selectFirst('notify', [], ['id' => $id, 'uid' => local_user()]);
-               if ($this->dba->isResult($stmtNotify)) {
-                       return $this->setExtra([$stmtNotify])[0];
+               try {
+                       $this->timestamp = strtotime(DateTimeFormat::local($this->date));
+               } catch (Exception $e) {
                }
-               return null;
-       }
-
-       /**
-        * set seen state of $note of local_user()
-        *
-        * @param array $note note array
-        * @param bool  $seen optional true or false, default true
-        *
-        * @return bool true on success, false on errors
-        * @throws Exception
-        */
-       public function setSeen(array $note, bool $seen = true)
-       {
-               return $this->dba->update('notify', ['seen' => $seen], [
-                       '(`link` = ? OR (`parent` != 0 AND `parent` = ? AND `otype` = ?)) AND `uid` = ?',
-                       $note['link'],
-                       $note['parent'],
-                       $note['otype'],
-                       local_user()
-               ]);
-       }
-
-       /**
-        * Set seen state of all notifications of local_user()
-        *
-        * @param bool $seen optional true or false. default true
-        *
-        * @return bool true on success, false on error
-        * @throws Exception
-        */
-       public function setAllSeen(bool $seen = true)
-       {
-               return $this->dba->update('notify', ['seen' => $seen], ['uid' => local_user()]);
+               $this->dateRel = Temporal::getRelativeDate($this->date);
        }
 
        /**
-        * Format the notification query in an usable array
-        *
-        * @param array  $notifies The array from the db query
-        * @param string $ident    The notifications identifier (e.g. network)
+        * Sets the pre-formatted name (caching)
         *
-        * @return array
-        *                       string 'label' => The type of the notification
-        *                       string 'link' => URL to the source
-        *                       string 'image' => The avatar image
-        *                       string 'url' => The profile url of the contact
-        *                       string 'text' => The notification text
-        *                       string 'when' => The date of the notification
-        *                       string 'ago' => T relative date of the notification
-        *                       bool 'seen' => Is the notification marked as "seen"
-        * @throws Exception
+        * @throws InternalServerErrorException
         */
-       private function formatList(array $notifies, string $ident = "")
+       private function setNameCache()
        {
-               $formattedNotifies = [];
-
-               foreach ($notifies as $notify) {
-                       // Because we use different db tables for the notification query
-                       // we have sometimes $notify['unseen'] and sometimes $notify['seen].
-                       // So we will have to transform $notify['unseen']
-                       if (array_key_exists('unseen', $notify)) {
-                               $notify['seen'] = ($notify['unseen'] > 0 ? false : true);
-                       }
-
-                       // For feed items we use the user's contact, since the avatar is mostly self choosen.
-                       if (!empty($notify['network']) && $notify['network'] == Protocol::FEED) {
-                               $notify['author-avatar'] = $notify['contact-avatar'];
-                       }
-
-                       // Depending on the identifier of the notification we need to use different defaults
-                       switch ($ident) {
-                               case self::SYSTEM:
-                                       $default_item_label = 'notify';
-                                       $default_item_link  = $this->baseUrl->get(true) . '/notify/view/' . $notify['id'];
-                                       $default_item_image = ProxyUtils::proxifyUrl($notify['photo'], false, ProxyUtils::SIZE_MICRO);
-                                       $default_item_url   = $notify['url'];
-                                       $default_item_text  = strip_tags(BBCode::convert($notify['msg']));
-                                       $default_item_when  = DateTimeFormat::local($notify['date'], 'r');
-                                       $default_item_ago   = Temporal::getRelativeDate($notify['date']);
-                                       break;
-
-                               case self::HOME:
-                                       $default_item_label = 'comment';
-                                       $default_item_link  = $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'];
-                                       $default_item_image = ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO);
-                                       $default_item_url   = $notify['author-link'];
-                                       $default_item_text  = $this->l10n->t("%s commented on %s's post", $notify['author-name'], $notify['parent-author-name']);
-                                       $default_item_when  = DateTimeFormat::local($notify['created'], 'r');
-                                       $default_item_ago   = Temporal::getRelativeDate($notify['created']);
-                                       break;
-
-                               default:
-                                       $default_item_label = (($notify['id'] == $notify['parent']) ? 'post' : 'comment');
-                                       $default_item_link  = $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'];
-                                       $default_item_image = ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO);
-                                       $default_item_url   = $notify['author-link'];
-                                       $default_item_text  = (($notify['id'] == $notify['parent'])
-                                               ? $this->l10n->t("%s created a new post", $notify['author-name'])
-                                               : $this->l10n->t("%s commented on %s's post", $notify['author-name'], $notify['parent-author-name']));
-                                       $default_item_when  = DateTimeFormat::local($notify['created'], 'r');
-                                       $default_item_ago   = Temporal::getRelativeDate($notify['created']);
-                       }
-
-                       // Transform the different types of notification in an usable array
-                       switch ($notify['verb']) {
-                               case Activity::LIKE:
-                                       $formattedNotify = [
-                                               'label' => 'like',
-                                               'link'  => $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'],
-                                               'image' => ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO),
-                                               'url'   => $notify['author-link'],
-                                               'text'  => $this->l10n->t("%s liked %s's post", $notify['author-name'], $notify['parent-author-name']),
-                                               'when'  => $default_item_when,
-                                               'ago'   => $default_item_ago,
-                                               'seen'  => $notify['seen']
-                                       ];
-                                       break;
-
-                               case Activity::DISLIKE:
-                                       $formattedNotify = [
-                                               'label' => 'dislike',
-                                               'link'  => $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'],
-                                               'image' => ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO),
-                                               'url'   => $notify['author-link'],
-                                               'text'  => $this->l10n->t("%s disliked %s's post", $notify['author-name'], $notify['parent-author-name']),
-                                               'when'  => $default_item_when,
-                                               'ago'   => $default_item_ago,
-                                               'seen'  => $notify['seen']
-                                       ];
-                                       break;
-
-                               case Activity::ATTEND:
-                                       $formattedNotify = [
-                                               'label' => 'attend',
-                                               'link'  => $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'],
-                                               'image' => ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO),
-                                               'url'   => $notify['author-link'],
-                                               'text'  => $this->l10n->t("%s is attending %s's event", $notify['author-name'], $notify['parent-author-name']),
-                                               'when'  => $default_item_when,
-                                               'ago'   => $default_item_ago,
-                                               'seen'  => $notify['seen']
-                                       ];
-                                       break;
-
-                               case Activity::ATTENDNO:
-                                       $formattedNotify = [
-                                               'label' => 'attendno',
-                                               'link'  => $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'],
-                                               'image' => ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO),
-                                               'url'   => $notify['author-link'],
-                                               'text'  => $this->l10n->t("%s is not attending %s's event", $notify['author-name'], $notify['parent-author-name']),
-                                               'when'  => $default_item_when,
-                                               'ago'   => $default_item_ago,
-                                               'seen'  => $notify['seen']
-                                       ];
-                                       break;
-
-                               case Activity::ATTENDMAYBE:
-                                       $formattedNotify = [
-                                               'label' => 'attendmaybe',
-                                               'link'  => $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'],
-                                               'image' => ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO),
-                                               'url'   => $notify['author-link'],
-                                               'text'  => $this->l10n->t("%s may attend %s's event", $notify['author-name'], $notify['parent-author-name']),
-                                               'when'  => $default_item_when,
-                                               'ago'   => $default_item_ago,
-                                               'seen'  => $notify['seen']
-                                       ];
-                                       break;
-
-                               case Activity::FRIEND:
-                                       if (!isset($notify['object'])) {
-                                               $formattedNotify = [
-                                                       'label' => 'friend',
-                                                       'link'  => $default_item_link,
-                                                       'image' => $default_item_image,
-                                                       'url'   => $default_item_url,
-                                                       'text'  => $default_item_text,
-                                                       'when'  => $default_item_when,
-                                                       'ago'   => $default_item_ago,
-                                                       'seen'  => $notify['seen']
-                                               ];
-                                               break;
-                                       }
-                                       /// @todo Check if this part here is used at all
-                                       $this->logger->info('Complete data.', ['notify' => $notify, 'callStack' => System::callstack(20)]);
-
-                                       $xmlHead         = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">";
-                                       $obj             = XML::parseString($xmlHead . $notify['object']);
-                                       $notify['fname'] = $obj->title;
-
-                                       $formattedNotify = [
-                                               'label' => 'friend',
-                                               'link'  => $this->baseUrl->get(true) . '/display/' . $notify['parent-guid'],
-                                               'image' => ProxyUtils::proxifyUrl($notify['author-avatar'], false, ProxyUtils::SIZE_MICRO),
-                                               'url'   => $notify['author-link'],
-                                               'text'  => $this->l10n->t("%s is now friends with %s", $notify['author-name'], $notify['fname']),
-                                               'when'  => $default_item_when,
-                                               'ago'   => $default_item_ago,
-                                               'seen'  => $notify['seen']
-                                       ];
-                                       break;
-
-                               default:
-                                       $formattedNotify = [
-                                               'label' => $default_item_label,
-                                               'link'  => $default_item_link,
-                                               'image' => $default_item_image,
-                                               'url'   => $default_item_url,
-                                               'text'  => $default_item_text,
-                                               'when'  => $default_item_when,
-                                               'ago'   => $default_item_ago,
-                                               'seen'  => $notify['seen']
-                                       ];
-                       }
-
-                       $formattedNotifies[] = $formattedNotify;
-               }
-
-               return $formattedNotifies;
+               $this->name_cache = strip_tags(BBCode::convert($this->source_name ?? ''));
        }
 
        /**
-        * Get network notifications
-        *
-        * @param bool $seen    False => only include notifications into the query
-        *                            which aren't marked as "seen"
-        * @param int        $start   Start the query at this point
-        * @param int        $limit   Maximum number of query results
-        *
-        * @return array [string, array]
-        *    string 'ident' => Notification identifier
-        *    array 'notifications' => Network notifications
-        *
-        * @throws Exception
-        */
-       public function getNetworkList(bool $seen = false, int $start = 0, int $limit = self::DEFAULT_PAGE_LIMIT)
-       {
-               $ident    = self::NETWORK;
-               $notifies = [];
-
-               $condition = ['wall' => false, 'uid' => local_user()];
-
-               if (!$seen) {
-                       $condition['unseen'] = true;
-               }
-
-               $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
-                       'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
-               $params = ['order' => ['received' => true], 'limit' => [$start, $limit]];
-
-               $items = Item::selectForUser(local_user(), $fields, $condition, $params);
-
-               if ($this->dba->isResult($items)) {
-                       $notifies = $this->formatList(Item::inArray($items), $ident);
-               }
-
-               $arr = [
-                       'notifications' => $notifies,
-                       'ident'         => $ident,
-               ];
-
-               return $arr;
-       }
-
-       /**
-        * Get system notifications
-        *
-        * @param bool $seen    False => only include notifications into the query
-        *                            which aren't marked as "seen"
-        * @param int        $start   Start the query at this point
-        * @param int        $limit   Maximum number of query results
-        *
-        * @return array [string, array]
-        *    string 'ident' => Notification identifier
-        *    array 'notifications' => System notifications
-        *
-        * @throws Exception
+        * Set some extra properties to the notification from db:
+        *  - msg_html: message as html string
+        *  - msg_plain: message as plain text string
+        *  - msg_cache: The pre-formatted message (caching)
         */
-       public function getSystemList(bool $seen = false, int $start = 0, int $limit = self::DEFAULT_PAGE_LIMIT)
+       private function setMsg()
        {
-               $ident    = self::SYSTEM;
-               $notifies = [];
-
-               $filter = ['uid' => local_user()];
-               if (!$seen) {
-                       $filter['seen'] = false;
-               }
-
-               $params          = [];
-               $params['order'] = ['date' => 'DESC'];
-               $params['limit'] = [$start, $limit];
-
-               $stmtNotifies = $this->dba->select('notify',
-                       ['id', 'url', 'photo', 'msg', 'date', 'seen', 'verb'],
-                       $filter,
-                       $params);
-
-               if ($this->dba->isResult($stmtNotifies)) {
-                       $notifies = $this->formatList($this->dba->toArray($stmtNotifies), $ident);
+               try {
+                       $this->msg_html  = BBCode::convert($this->msg, false);
+                       $this->msg_plain = explode("\n", trim(HTML::toPlaintext($this->msg_html, 0)))[0];
+                       $this->msg_cache = self::formatMessage($this->name_cache, strip_tags(BBCode::convert($this->msg)));
+               } catch (InternalServerErrorException $e) {
                }
-
-               $arr = [
-                       'notifications' => $notifies,
-                       'ident'         => $ident,
-               ];
-
-               return $arr;
        }
 
-       /**
-        * Get personal notifications
-        *
-        * @param bool $seen    False => only include notifications into the query
-        *                            which aren't marked as "seen"
-        * @param int        $start   Start the query at this point
-        * @param int        $limit   Maximum number of query results
-        *
-        * @return array [string, array]
-        *    string 'ident' => Notification identifier
-        *    array 'notifications' => Personal notifications
-        *
-        * @throws Exception
-        */
-       public function getPersonalList(bool $seen = false, int $start = 0, int $limit = self::DEFAULT_PAGE_LIMIT)
+       public function __set($name, $value)
        {
-               $ident    = self::PERSONAL;
-               $notifies = [];
+               parent::__set($name, $value);
 
-               $myurl     = str_replace('http://', '', DI::app()->contact['nurl']);
-               $diasp_url = str_replace('/profile/', '/u/', $myurl);
-
-               $condition = ["NOT `wall` AND `uid` = ? AND (`item`.`author-id` = ? OR `item`.`tag` REGEXP ? OR `item`.`tag` REGEXP ?)",
-                       local_user(), public_contact(), $myurl . '\\]', $diasp_url . '\\]'];
-
-               if (!$seen) {
-                       $condition[0] .= " AND `unseen`";
+               if ($name == 'date') {
+                       $this->setTimestamp();
                }
 
-               $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
-                       'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
-               $params = ['order' => ['received' => true], 'limit' => [$start, $limit]];
-
-               $items = Item::selectForUser(local_user(), $fields, $condition, $params);
-
-               if ($this->dba->isResult($items)) {
-                       $notifies = $this->formatList(Item::inArray($items), $ident);
+               if ($name == 'msg') {
+                       $this->setMsg();
                }
 
-               $arr = [
-                       'notifications' => $notifies,
-                       'ident'         => $ident,
-               ];
-
-               return $arr;
-       }
-
-       /**
-        * Get home notifications
-        *
-        * @param bool $seen    False => only include notifications into the query
-        *                            which aren't marked as "seen"
-        * @param int        $start   Start the query at this point
-        * @param int        $limit   Maximum number of query results
-        *
-        * @return array [string, array]
-        *    string 'ident' => Notification identifier
-        *    array 'notifications' => Home notifications
-        *
-        * @throws Exception
-        */
-       public function getHomeList(bool $seen = false, int $start = 0, int $limit = self::DEFAULT_PAGE_LIMIT)
-       {
-               $ident    = self::HOME;
-               $notifies = [];
-
-               $condition = ['wall' => true, 'uid' => local_user()];
-
-               if (!$seen) {
-                       $condition['unseen'] = true;
+               if ($name == 'source_name') {
+                       $this->setNameCache();
                }
-
-               $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
-                       'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
-               $params = ['order' => ['received' => true], 'limit' => [$start, $limit]];
-
-               $items = Item::selectForUser(local_user(), $fields, $condition, $params);
-
-               if ($this->dba->isResult($items)) {
-                       $notifies = $this->formatList(Item::inArray($items), $ident);
-               }
-
-               $arr = [
-                       'notifications' => $notifies,
-                       'ident'         => $ident,
-               ];
-
-               return $arr;
        }
 
        /**
-        * Get introductions
+        * Formats a notification message with the notification author
         *
-        * @param bool $all     If false only include introductions into the query
-        *                      which aren't marked as ignored
-        * @param int  $start   Start the query at this point
-        * @param int  $limit   Maximum number of query results
-        * @param int  $id      When set, only the introduction with this id is displayed
+        * Replace the name with {0} but ensure to make that only once. The {0} is used
+        * later and prints the name in bold.
         *
-        * @return array [string, array]
-        *    string 'ident' => Notification identifier
-        *    array 'notifications' => Introductions
+        * @param string $name
+        * @param string $message
         *
-        * @throws ImagickException
-        * @throws Exception
+        * @return string Formatted message
         */
-       public function getIntroList(bool $all = false, int $start = 0, int $limit = self::DEFAULT_PAGE_LIMIT, int $id = 0)
+       public static function formatMessage($name, $message)
        {
-               /// @todo sanitize wording according to SELF::INTRO
-               $ident     = 'introductions';
-               $notifies  = [];
-               $sql_extra = "";
-
-               if (empty($id)) {
-                       if (!$all) {
-                               $sql_extra = " AND NOT `ignore` ";
-                       }
-
-                       $sql_extra .= " AND NOT `intro`.`blocked` ";
+               if ($name != '') {
+                       $pos = strpos($message, $name);
                } else {
-                       $sql_extra = sprintf(" AND `intro`.`id` = %d ", intval($id));
+                       $pos = false;
                }
 
-               /// @todo Fetch contact details by "Contact::getDetailsByUrl" instead of queries to contact, fcontact and gcontact
-               $stmtNotifies = $this->dba->p(
-                       "SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*,
-                               `fcontact`.`name` AS `fname`, `fcontact`.`url` AS `furl`, `fcontact`.`addr` AS `faddr`,
-                               `fcontact`.`photo` AS `fphoto`, `fcontact`.`request` AS `frequest`,
-                               `gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`,
-                               `gcontact`.`keywords` AS `gkeywords`, `gcontact`.`gender` AS `ggender`,
-                               `gcontact`.`network` AS `gnetwork`, `gcontact`.`addr` AS `gaddr`
-                       FROM `intro`
-                               LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
-                               LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
-                               LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
-                       WHERE `intro`.`uid` = ? $sql_extra
-                       LIMIT ?, ?",
-                       $_SESSION['uid'],
-                       $start,
-                       $limit
-               );
-               if ($this->dba->isResult($stmtNotifies)) {
-                       $notifies = $this->formatIntroList($this->dba->toArray($stmtNotifies));
-               }
-
-               $arr = [
-                       'ident'         => $ident,
-                       'notifications' => $notifies,
-               ];
-
-               return $arr;
-       }
-
-       /**
-        * Format the notification query in an usable array
-        *
-        * @param array $intros The array from the db query
-        *
-        * @return array with the introductions
-        * @throws HTTPException\InternalServerErrorException
-        * @throws ImagickException
-        */
-       private function formatIntroList(array $intros)
-       {
-               $knowyou = '';
-
-               $formattedIntros = [];
-
-               foreach ($intros as $intro) {
-                       // There are two kind of introduction. Contacts suggested by other contacts and normal connection requests.
-                       // We have to distinguish between these two because they use different data.
-                       // Contact suggestions
-                       if ($intro['fid']) {
-                               $return_addr = bin2hex(DI::app()->user['nickname'] . '@' .
-                                                      $this->baseUrl->getHostName() .
-                                                      (($this->baseUrl->getURLPath()) ? '/' . $this->baseUrl->getURLPath() : ''));
-
-                               $intro = [
-                                       'label'          => 'friend_suggestion',
-                                       'notify_type'    => $this->l10n->t('Friend Suggestion'),
-                                       'intro_id'       => $intro['intro_id'],
-                                       'madeby'         => $intro['name'],
-                                       'madeby_url'     => $intro['url'],
-                                       'madeby_zrl'     => Contact::magicLink($intro['url']),
-                                       'madeby_addr'    => $intro['addr'],
-                                       'contact_id'     => $intro['contact-id'],
-                                       'photo'          => (!empty($intro['fphoto']) ? ProxyUtils::proxifyUrl($intro['fphoto'], false, ProxyUtils::SIZE_SMALL) : "images/person-300.jpg"),
-                                       'name'           => $intro['fname'],
-                                       'url'            => $intro['furl'],
-                                       'zrl'            => Contact::magicLink($intro['furl']),
-                                       'hidden'         => $intro['hidden'] == 1,
-                                       'post_newfriend' => (intval($this->pConfig->get(local_user(), 'system', 'post_newfriend')) ? '1' : 0),
-                                       'knowyou'        => $knowyou,
-                                       'note'           => $intro['note'],
-                                       'request'        => $intro['frequest'] . '?addr=' . $return_addr,
-                               ];
-
-                               // Normal connection requests
-                       } else {
-                               $intro = $this->getMissingIntroData($intro);
-
-                               if (empty($intro['url'])) {
-                                       continue;
-                               }
-
-                               // Don't show these data until you are connected. Diaspora is doing the same.
-                               if ($intro['gnetwork'] === Protocol::DIASPORA) {
-                                       $intro['glocation'] = "";
-                                       $intro['gabout']    = "";
-                                       $intro['ggender']   = "";
-                               }
-                               $intro = [
-                                       'label'          => (($intro['network'] !== Protocol::OSTATUS) ? 'friend_request' : 'follower'),
-                                       'notify_type'    => (($intro['network'] !== Protocol::OSTATUS) ? $this->l10n->t('Friend/Connect Request') : $this->l10n->t('New Follower')),
-                                       'dfrn_id'        => $intro['issued-id'],
-                                       'uid'            => $_SESSION['uid'],
-                                       'intro_id'       => $intro['intro_id'],
-                                       'contact_id'     => $intro['contact-id'],
-                                       'photo'          => (!empty($intro['photo']) ? ProxyUtils::proxifyUrl($intro['photo'], false, ProxyUtils::SIZE_SMALL) : "images/person-300.jpg"),
-                                       'name'           => $intro['name'],
-                                       'location'       => BBCode::convert($intro['glocation'], false),
-                                       'about'          => BBCode::convert($intro['gabout'], false),
-                                       'keywords'       => $intro['gkeywords'],
-                                       'gender'         => $intro['ggender'],
-                                       'hidden'         => $intro['hidden'] == 1,
-                                       'post_newfriend' => (intval($this->pConfig->get(local_user(), 'system', 'post_newfriend')) ? '1' : 0),
-                                       'url'            => $intro['url'],
-                                       'zrl'            => Contact::magicLink($intro['url']),
-                                       'addr'           => $intro['gaddr'],
-                                       'network'        => $intro['gnetwork'],
-                                       'knowyou'        => $intro['knowyou'],
-                                       'note'           => $intro['note'],
-                               ];
-                       }
-
-                       $formattedIntros[] = $intro;
-               }
-
-               return $formattedIntros;
-       }
-
-       /**
-        * Check for missing contact data and try to fetch the data from
-        * from other sources
-        *
-        * @param array $intro The input array with the intro data
-        *
-        * @return array The array with the intro data
-        * @throws HTTPException\InternalServerErrorException
-        */
-       private function getMissingIntroData(array $intro)
-       {
-               // If the network and the addr isn't available from the gcontact
-               // table entry, take the one of the contact table entry
-               if (empty($intro['gnetwork']) && !empty($intro['network'])) {
-                       $intro['gnetwork'] = $intro['network'];
-               }
-               if (empty($intro['gaddr']) && !empty($intro['addr'])) {
-                       $intro['gaddr'] = $intro['addr'];
-               }
-
-               // If the network and addr is still not available
-               // get the missing data data from other sources
-               if (empty($intro['gnetwork']) || empty($intro['gaddr'])) {
-                       $ret = Contact::getDetailsByURL($intro['url']);
-
-                       if (empty($intro['gnetwork']) && !empty($ret['network'])) {
-                               $intro['gnetwork'] = $ret['network'];
-                       }
-                       if (empty($intro['gaddr']) && !empty($ret['addr'])) {
-                               $intro['gaddr'] = $ret['addr'];
-                       }
+               if ($pos !== false) {
+                       $message = substr_replace($message, '{0}', $pos, strlen($name));
                }
 
-               return $intro;
+               return $message;
        }
 }
index b993562cecc76ab140266ae3e48458f49a114336..18b09225e780cad1e661fa8ee8395a1fac1eed4a 100644 (file)
@@ -5,10 +5,7 @@
 namespace Friendica\Model;
 
 use Friendica\App;
-use Friendica\Content\Feature;
-use Friendica\Content\ForumManager;
 use Friendica\Content\Text\BBCode;
-use Friendica\Content\Text\HTML;
 use Friendica\Content\Widget\ContactBlock;
 use Friendica\Core\Cache\Duration;
 use Friendica\Core\Hook;
@@ -25,7 +22,6 @@ use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Network;
 use Friendica\Util\Proxy as ProxyUtils;
 use Friendica\Util\Strings;
-use Friendica\Util\Temporal;
 
 class Profile
 {
@@ -39,8 +35,7 @@ class Profile
         */
        public static function getByUID($uid)
        {
-               $profile = DBA::selectFirst('profile', [], ['uid' => $uid, 'is-default' => true]);
-               return $profile;
+               return DBA::selectFirst('profile', [], ['uid' => $uid]);
        }
 
        /**
@@ -155,7 +150,7 @@ class Profile
                        }
                }
 
-               $profile = self::getByNickname($nickname, $user['uid'], $profile_id);
+               $profile = self::getByNickname($nickname, $user['uid']);
 
                if (empty($profile) && empty($profiledata)) {
                        Logger::log('profile error: ' . DI::args()->getQueryString(), Logger::DEBUG);
@@ -163,17 +158,7 @@ class Profile
                }
 
                if (empty($profile)) {
-                       $profile = ['uid' => 0, 'is-default' => false,'name' => $nickname];
-               }
-
-               // fetch user tags if this isn't the default profile
-
-               if (!$profile['is-default']) {
-                       $condition = ['uid' => $profile['uid'], 'is-default' => true];
-                       $profile_id = DBA::selectFirst('profile', ['pub_keywords'], $condition);
-                       if (DBA::isResult($profile_id)) {
-                               $profile['pub_keywords'] = $profile_id['pub_keywords'];
-                       }
+                       $profile = ['uid' => 0, 'name' => $nickname];
                }
 
                $a->profile = $profile;
@@ -202,7 +187,7 @@ class Profile
 
                if (local_user() && local_user() == $a->profile['uid'] && $profiledata) {
                        DI::page()['aside'] .= Renderer::replaceMacros(
-                               Renderer::getMarkupTemplate('profile_edlink.tpl'),
+                               Renderer::getMarkupTemplate('settings/profile/link.tpl'),
                                [
                                        '$editprofile' => DI::l10n()->t('Edit profile'),
                                        '$profid' => $a->profile['id']
@@ -240,44 +225,20 @@ class Profile
         * @return array
         * @throws \Exception
         */
-       public static function getByNickname($nickname, $uid = 0, $profile_id = 0)
+       public static function getByNickname($nickname, $uid = 0)
        {
-               if (!empty(Session::getRemoteContactID($uid))) {
-                       $contact = DBA::selectFirst('contact', ['profile-id'], ['id' => Session::getRemoteContactID($uid)]);
-                       if (DBA::isResult($contact)) {
-                               $profile_id = $contact['profile-id'];
-                       }
-               }
-
-               $profile = null;
-
-               if ($profile_id) {
-                       $profile = DBA::fetchFirst(
-                               "SELECT `contact`.`id` AS `contact_id`, `contact`.`photo` AS `contact_photo`,
-                                       `contact`.`thumb` AS `contact_thumb`, `contact`.`micro` AS `contact_micro`,
-                                       `profile`.*,
-                                       `contact`.`avatar-date` AS picdate, `contact`.`addr`, `contact`.`url`, `user`.*
-                               FROM `profile`
-                               INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` AND `contact`.`self`
-                               INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
-                               WHERE `user`.`nickname` = ? AND `profile`.`id` = ? LIMIT 1",
-                               $nickname,
-                               intval($profile_id)
-                       );
-               }
-               if (!DBA::isResult($profile)) {
-                       $profile = DBA::fetchFirst(
-                               "SELECT `contact`.`id` AS `contact_id`, `contact`.`photo` as `contact_photo`,
-                                       `contact`.`thumb` AS `contact_thumb`, `contact`.`micro` AS `contact_micro`,
-                                       `profile`.*,
-                                       `contact`.`avatar-date` AS picdate, `contact`.`addr`, `contact`.`url`, `user`.*
-                               FROM `profile`
-                               INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid` AND `contact`.`self`
-                               INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
-                               WHERE `user`.`nickname` = ? AND `profile`.`is-default` LIMIT 1",
-                               $nickname
-                       );
-               }
+               $profile = DBA::fetchFirst(
+                       "SELECT `contact`.`id` AS `contact_id`, `contact`.`photo` AS `contact_photo`,
+                               `contact`.`thumb` AS `contact_thumb`, `contact`.`micro` AS `contact_micro`,
+                               `profile`.*,
+                               `contact`.`avatar-date` AS picdate, `contact`.`addr`, `contact`.`url`, `user`.*
+                       FROM `profile`
+                       INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` AND `contact`.`self`
+                       INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
+                       WHERE `user`.`nickname` = ? AND `profile`.`uid` = ? LIMIT 1",
+                       $nickname,
+                       intval($uid)
+               );
 
                return $profile;
        }
@@ -388,40 +349,12 @@ class Profile
 
                // show edit profile to yourself
                if (!$is_contact && $local_user_is_self) {
-                       if (Feature::isEnabled(local_user(), 'multi_profiles')) {
-                               $profile['edit'] = [DI::baseUrl() . '/profiles', DI::l10n()->t('Profiles'), '', DI::l10n()->t('Manage/edit profiles')];
-                               $r = q(
-                                       "SELECT * FROM `profile` WHERE `uid` = %d",
-                                       local_user()
-                               );
-
-                               $profile['menu'] = [
-                                       'chg_photo' => DI::l10n()->t('Change profile photo'),
-                                       'cr_new' => DI::l10n()->t('Create New Profile'),
-                                       'entries' => [],
-                               ];
-
-                               if (DBA::isResult($r)) {
-                                       foreach ($r as $rr) {
-                                               $profile['menu']['entries'][] = [
-                                                       'photo' => $rr['thumb'],
-                                                       'id' => $rr['id'],
-                                                       'alt' => DI::l10n()->t('Profile Image'),
-                                                       'profile_name' => $rr['profile-name'],
-                                                       'isdefault' => $rr['is-default'],
-                                                       'visibile_to_everybody' => DI::l10n()->t('visible to everybody'),
-                                                       'edit_visibility' => DI::l10n()->t('Edit visibility'),
-                                               ];
-                                       }
-                               }
-                       } else {
-                               $profile['edit'] = [DI::baseUrl() . '/profiles/' . $profile['id'], DI::l10n()->t('Edit profile'), '', DI::l10n()->t('Edit profile')];
-                               $profile['menu'] = [
-                                       'chg_photo' => DI::l10n()->t('Change profile photo'),
-                                       'cr_new' => null,
-                                       'entries' => [],
-                               ];
-                       }
+                       $profile['edit'] = [DI::baseUrl() . '/settings/profile', DI::l10n()->t('Edit profile'), '', DI::l10n()->t('Edit profile')];
+                       $profile['menu'] = [
+                               'chg_photo' => DI::l10n()->t('Change profile photo'),
+                               'cr_new' => null,
+                               'entries' => [],
+                       ];
                }
 
                // Fetch the account type
@@ -742,263 +675,6 @@ class Profile
                ]);
        }
 
-       public static function getAdvanced(App $a)
-       {
-               $uid = intval($a->profile['uid']);
-
-               if ($a->profile['name']) {
-                       $profile = [];
-
-                       $profile['fullname'] = [DI::l10n()->t('Full Name:'), $a->profile['name']];
-
-                       if (Feature::isEnabled($uid, 'profile_membersince')) {
-                               $profile['membersince'] = [DI::l10n()->t('Member since:'), DateTimeFormat::local($a->profile['register_date'])];
-                       }
-
-                       if ($a->profile['gender']) {
-                               $profile['gender'] = [DI::l10n()->t('Gender:'), DI::l10n()->t($a->profile['gender'])];
-                       }
-
-                       if (!empty($a->profile['dob']) && $a->profile['dob'] > DBA::NULL_DATE) {
-                               $year_bd_format = DI::l10n()->t('j F, Y');
-                               $short_bd_format = DI::l10n()->t('j F');
-
-                               $val = DI::l10n()->getDay(
-                                       intval($a->profile['dob']) ?
-                                               DateTimeFormat::utc($a->profile['dob'] . ' 00:00 +00:00', $year_bd_format)
-                                               : DateTimeFormat::utc('2001-' . substr($a->profile['dob'], 5) . ' 00:00 +00:00', $short_bd_format)
-                               );
-
-                               $profile['birthday'] = [DI::l10n()->t('Birthday:'), $val];
-                       }
-
-                       if (!empty($a->profile['dob'])
-                               && $a->profile['dob'] > DBA::NULL_DATE
-                               && $age = Temporal::getAgeByTimezone($a->profile['dob'], $a->profile['timezone'])
-                       ) {
-                               $profile['age'] = [DI::l10n()->t('Age: ') , DI::l10n()->tt('%d year old', '%d years old', $age)];
-                       }
-
-                       if ($a->profile['marital']) {
-                               $profile['marital'] = [DI::l10n()->t('Status:'), DI::l10n()->t($a->profile['marital'])];
-                       }
-
-                       /// @TODO Maybe use x() here, plus below?
-                       if ($a->profile['with']) {
-                               $profile['marital']['with'] = $a->profile['with'];
-                       }
-
-                       if (strlen($a->profile['howlong']) && $a->profile['howlong'] > DBA::NULL_DATETIME) {
-                               $profile['howlong'] = Temporal::getRelativeDate($a->profile['howlong'], DI::l10n()->t('for %1$d %2$s'));
-                       }
-
-                       if ($a->profile['sexual']) {
-                               $profile['sexual'] = [DI::l10n()->t('Sexual Preference:'), DI::l10n()->t($a->profile['sexual'])];
-                       }
-
-                       if ($a->profile['homepage']) {
-                               $profile['homepage'] = [DI::l10n()->t('Homepage:'), HTML::toLink($a->profile['homepage'])];
-                       }
-
-                       if ($a->profile['hometown']) {
-                               $profile['hometown'] = [DI::l10n()->t('Hometown:'), HTML::toLink($a->profile['hometown'])];
-                       }
-
-                       if ($a->profile['pub_keywords']) {
-                               $profile['pub_keywords'] = [DI::l10n()->t('Tags:'), $a->profile['pub_keywords']];
-                       }
-
-                       if ($a->profile['politic']) {
-                               $profile['politic'] = [DI::l10n()->t('Political Views:'), $a->profile['politic']];
-                       }
-
-                       if ($a->profile['religion']) {
-                               $profile['religion'] = [DI::l10n()->t('Religion:'), $a->profile['religion']];
-                       }
-
-                       if ($txt = BBCode::convert($a->profile['about'])) {
-                               $profile['about'] = [DI::l10n()->t('About:'), $txt];
-                       }
-
-                       if ($txt = BBCode::convert($a->profile['interest'])) {
-                               $profile['interest'] = [DI::l10n()->t('Hobbies/Interests:'), $txt];
-                       }
-
-                       if ($txt = BBCode::convert($a->profile['likes'])) {
-                               $profile['likes'] = [DI::l10n()->t('Likes:'), $txt];
-                       }
-
-                       if ($txt = BBCode::convert($a->profile['dislikes'])) {
-                               $profile['dislikes'] = [DI::l10n()->t('Dislikes:'), $txt];
-                       }
-
-                       if ($txt = BBCode::convert($a->profile['contact'])) {
-                               $profile['contact'] = [DI::l10n()->t('Contact information and Social Networks:'), $txt];
-                       }
-
-                       if ($txt = BBCode::convert($a->profile['music'])) {
-                               $profile['music'] = [DI::l10n()->t('Musical interests:'), $txt];
-                       }
-
-                       if ($txt = BBCode::convert($a->profile['book'])) {
-                               $profile['book'] = [DI::l10n()->t('Books, literature:'), $txt];
-                       }
-
-                       if ($txt = BBCode::convert($a->profile['tv'])) {
-                               $profile['tv'] = [DI::l10n()->t('Television:'), $txt];
-                       }
-
-                       if ($txt = BBCode::convert($a->profile['film'])) {
-                               $profile['film'] = [DI::l10n()->t('Film/dance/culture/entertainment:'), $txt];
-                       }
-
-                       if ($txt = BBCode::convert($a->profile['romance'])) {
-                               $profile['romance'] = [DI::l10n()->t('Love/Romance:'), $txt];
-                       }
-
-                       if ($txt = BBCode::convert($a->profile['work'])) {
-                               $profile['work'] = [DI::l10n()->t('Work/employment:'), $txt];
-                       }
-
-                       if ($txt = BBCode::convert($a->profile['education'])) {
-                               $profile['education'] = [DI::l10n()->t('School/education:'), $txt];
-                       }
-
-                       //show subcribed forum if it is enabled in the usersettings
-                       if (Feature::isEnabled($uid, 'forumlist_profile')) {
-                               $profile['forumlist'] = [DI::l10n()->t('Forums:'), ForumManager::profileAdvanced($uid)];
-                       }
-
-                       if ($a->profile['uid'] == local_user()) {
-                               $profile['edit'] = [DI::baseUrl() . '/profiles/' . $a->profile['id'], DI::l10n()->t('Edit profile'), '', DI::l10n()->t('Edit profile')];
-                       }
-
-                       $tpl = Renderer::getMarkupTemplate('profile/advanced.tpl');
-                       return Renderer::replaceMacros($tpl, [
-                               '$title' => DI::l10n()->t('Profile'),
-                               '$basic' => DI::l10n()->t('Basic'),
-                               '$advanced' => DI::l10n()->t('Advanced'),
-                               '$profile' => $profile
-                       ]);
-               }
-
-               return '';
-       }
-
-    /**
-     * @param App    $a
-     * @param string $current
-     * @param bool   $is_owner
-     * @param string $nickname
-     * @return string
-     * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-     */
-       public static function getTabs(App $a, string $current, bool $is_owner, string $nickname = null)
-       {
-               if (is_null($nickname)) {
-                       $nickname = $a->user['nickname'];
-               }
-
-               $baseProfileUrl = DI::baseUrl() . '/profile/' . $nickname;
-
-               $tabs = [
-                       [
-                               'label' => DI::l10n()->t('Status'),
-                               'url'   => $baseProfileUrl,
-                               'sel'   => !$current ? 'active' : '',
-                               'title' => DI::l10n()->t('Status Messages and Posts'),
-                               'id'    => 'status-tab',
-                               'accesskey' => 'm',
-                       ],
-                       [
-                               'label' => DI::l10n()->t('Profile'),
-                               'url'   => $baseProfileUrl . '/?tab=profile',
-                               'sel'   => $current == 'profile' ? 'active' : '',
-                               'title' => DI::l10n()->t('Profile Details'),
-                               'id'    => 'profile-tab',
-                               'accesskey' => 'r',
-                       ],
-                       [
-                               'label' => DI::l10n()->t('Photos'),
-                               'url'   => DI::baseUrl() . '/photos/' . $nickname,
-                               'sel'   => $current == 'photos' ? 'active' : '',
-                               'title' => DI::l10n()->t('Photo Albums'),
-                               'id'    => 'photo-tab',
-                               'accesskey' => 'h',
-                       ],
-                       [
-                               'label' => DI::l10n()->t('Videos'),
-                               'url'   => DI::baseUrl() . '/videos/' . $nickname,
-                               'sel'   => $current == 'videos' ? 'active' : '',
-                               'title' => DI::l10n()->t('Videos'),
-                               'id'    => 'video-tab',
-                               'accesskey' => 'v',
-                       ],
-               ];
-
-               // the calendar link for the full featured events calendar
-               if ($is_owner && $a->theme_events_in_profile) {
-                       $tabs[] = [
-                               'label' => DI::l10n()->t('Events'),
-                               'url'   => DI::baseUrl() . '/events',
-                               'sel'   => $current == 'events' ? 'active' : '',
-                               'title' => DI::l10n()->t('Events and Calendar'),
-                               'id'    => 'events-tab',
-                               'accesskey' => 'e',
-                       ];
-                       // if the user is not the owner of the calendar we only show a calendar
-                       // with the public events of the calendar owner
-               } elseif (!$is_owner) {
-                       $tabs[] = [
-                               'label' => DI::l10n()->t('Events'),
-                               'url'   => DI::baseUrl() . '/cal/' . $nickname,
-                               'sel'   => $current == 'cal' ? 'active' : '',
-                               'title' => DI::l10n()->t('Events and Calendar'),
-                               'id'    => 'events-tab',
-                               'accesskey' => 'e',
-                       ];
-               }
-
-               if ($is_owner) {
-                       $tabs[] = [
-                               'label' => DI::l10n()->t('Personal Notes'),
-                               'url'   => DI::baseUrl() . '/notes',
-                               'sel'   => $current == 'notes' ? 'active' : '',
-                               'title' => DI::l10n()->t('Only You Can See This'),
-                               'id'    => 'notes-tab',
-                               'accesskey' => 't',
-                       ];
-               }
-
-               if (!empty($_SESSION['new_member']) && $is_owner) {
-                       $tabs[] = [
-                               'label' => DI::l10n()->t('Tips for New Members'),
-                               'url'   => DI::baseUrl() . '/newmember',
-                               'sel'   => false,
-                               'title' => DI::l10n()->t('Tips for New Members'),
-                               'id'    => 'newmember-tab',
-                       ];
-               }
-
-               if ($is_owner || empty($a->profile['hide-friends'])) {
-                       $tabs[] = [
-                               'label' => DI::l10n()->t('Contacts'),
-                               'url'   => $baseProfileUrl . '/contacts',
-                               'sel'   => $current == 'contacts' ? 'active' : '',
-                               'title' => DI::l10n()->t('Contacts'),
-                               'id'    => 'viewcontacts-tab',
-                               'accesskey' => 'k',
-                       ];
-               }
-
-               $arr = ['is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => $current, 'tabs' => $tabs];
-               Hook::callAll('profile_tabs', $arr);
-
-               $tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
-
-               return Renderer::replaceMacros($tpl, ['$tabs' => $arr['tabs']]);
-       }
-
        /**
         * Retrieves the my_url session variable
         *
@@ -1229,7 +905,7 @@ class Profile
         */
        public static function searchProfiles($start = 0, $count = 100, $search = null)
        {
-               $publish = (DI::config()->get('system', 'publish_all') ? '' : " AND `publish` = 1 ");
+               $publish = (DI::config()->get('system', 'publish_all') ? '' : "`publish` = 1");
                $total = 0;
 
                if (!empty($search)) {
@@ -1237,7 +913,7 @@ class Profile
                        $cnt = DBA::fetchFirst("SELECT COUNT(*) AS `total`
                                FROM `profile`
                                LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
-                               WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed`
+                               WHERE $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed`
                                AND ((`profile`.`name` LIKE ?) OR
                                (`user`.`nickname` LIKE ?) OR
                                (`profile`.`pdesc` LIKE ?) OR
@@ -1259,7 +935,7 @@ class Profile
                        $cnt = DBA::fetchFirst("SELECT COUNT(*) AS `total`
                                FROM `profile`
                                LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
-                               WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed`");
+                               WHERE $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed`");
                }
 
                if (DBA::isResult($cnt)) {
@@ -1279,7 +955,7 @@ class Profile
                        FROM `profile`
                        LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
                        LEFT JOIN `contact` ON `contact`.`uid` = `user`.`uid`
-                       WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` AND `contact`.`self`
+                       WHERE $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` AND `contact`.`self`
                        AND ((`profile`.`name` LIKE ?) OR
                                (`user`.`nickname` LIKE ?) OR
                                (`profile`.`pdesc` LIKE ?) OR
@@ -1306,7 +982,7 @@ class Profile
                        FROM `profile`
                        LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
                        LEFT JOIN `contact` ON `contact`.`uid` = `user`.`uid`
-                       WHERE `is-default` $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` AND `contact`.`self`
+                       WHERE $publish AND NOT `user`.`blocked` AND NOT `user`.`account_removed` AND `contact`.`self`
                        $order LIMIT ?,?",
                                        $start, $count
                                );
diff --git a/src/Model/ProfileField.php b/src/Model/ProfileField.php
new file mode 100644 (file)
index 0000000..e4192a9
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+
+namespace Friendica\Model;
+
+use Friendica\BaseModel;
+use Friendica\Database\Database;
+use Friendica\Network\HTTPException;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Custom profile field model class.
+ *
+ * Custom profile fields are user-created arbitrary profile fields that can be assigned a permission set to restrict its
+ * display to specific Friendica contacts as it requires magic authentication to work.
+ *
+ * @property int    uid
+ * @property int    order
+ * @property int    psid
+ * @property string label
+ * @property string value
+ * @property string created
+ * @property string edited
+ * @property PermissionSet permissionset
+ */
+class ProfileField extends BaseModel
+{
+       /** @var PermissionSet */
+       private $permissionset;
+
+       /** @var \Friendica\Repository\PermissionSet */
+       private $permissionSetRepository;
+
+       public function __construct(Database $dba, LoggerInterface $logger, \Friendica\Repository\PermissionSet $permissionSetRepository, array $data = [])
+       {
+               parent::__construct($dba, $logger, $data);
+
+               $this->permissionSetRepository = $permissionSetRepository;
+       }
+
+       public function __get($name)
+       {
+               $this->checkValid();
+
+               switch ($name) {
+                       case 'permissionset':
+                               $this->permissionset =
+                                       $this->permissionset ??
+                                               $this->permissionSetRepository->selectFirst(['id' => $this->psid, 'uid' => $this->uid]);
+
+                               $return = $this->permissionset;
+                               break;
+                       default:
+                               $return = parent::__get($name);
+                               break;
+               }
+
+               return $return;
+       }
+}
index 0e8d11f7339e461d8f52c3222be36a220325eb3e..fd7238819d23ad293d1df1e7114ca90c0287889d 100644 (file)
@@ -782,9 +782,7 @@ class User
                        'photo' => DI::baseUrl() . "/photo/profile/{$uid}.jpg",
                        'thumb' => DI::baseUrl() . "/photo/avatar/{$uid}.jpg",
                        'publish' => $publish,
-                       'is-default' => 1,
                        'net-publish' => $netpublish,
-                       'profile-name' => DI::l10n()->t('default')
                ]);
                if (!$insert_result) {
                        DBA::delete('user', ['uid' => $uid]);
@@ -1113,7 +1111,7 @@ class User
 
                $userStmt = DBA::p("SELECT `user`.`uid`, `user`.`login_date`, `contact`.`last-item`
                        FROM `user`
-                       INNER JOIN `profile` ON `profile`.`uid` = `user`.`uid` AND `profile`.`is-default`
+                       INNER JOIN `profile` ON `profile`.`uid` = `user`.`uid`
                        INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self`
                        WHERE (`profile`.`publish` OR `profile`.`net-publish`) AND `user`.`verified`
                                AND NOT `user`.`blocked` AND NOT `user`.`account_removed`
diff --git a/src/Module/BaseNotifications.php b/src/Module/BaseNotifications.php
new file mode 100644 (file)
index 0000000..9a67bb5
--- /dev/null
@@ -0,0 +1,177 @@
+<?php
+
+namespace Friendica\Module;
+
+use Exception;
+use Friendica\BaseModule;
+use Friendica\Content\Pager;
+use Friendica\Core\Renderer;
+use Friendica\Core\System;
+use Friendica\DI;
+use Friendica\Network\HTTPException\ForbiddenException;
+use Friendica\Object\Notification\Notification;
+
+/**
+ * Base Module for each tab of the notification display
+ *
+ * General possibility to print it as JSON as well
+ */
+abstract class BaseNotifications extends BaseModule
+{
+       /** @var array Array of URL parameters */
+       const URL_TYPES = [
+               Notification::NETWORK  => 'network',
+               Notification::SYSTEM   => 'system',
+               Notification::HOME     => 'home',
+               Notification::PERSONAL => 'personal',
+               Notification::INTRO    => 'intros',
+       ];
+
+       /** @var array Array of the allowed notifications and their printable name */
+       const PRINT_TYPES = [
+               Notification::NETWORK  => 'Network',
+               Notification::SYSTEM   => 'System',
+               Notification::HOME     => 'Home',
+               Notification::PERSONAL => 'Personal',
+               Notification::INTRO    => 'Introductions',
+       ];
+
+       /** @var array The array of access keys for notification pages */
+       const ACCESS_KEYS = [
+               Notification::NETWORK  => 'w',
+               Notification::SYSTEM   => 'y',
+               Notification::HOME     => 'h',
+               Notification::PERSONAL => 'r',
+               Notification::INTRO    => 'i',
+       ];
+
+       /** @var int The default count of items per page */
+       const ITEMS_PER_PAGE = 20;
+       /** @var int The default limit of notifications per page */
+       const DEFAULT_PAGE_LIMIT = 80;
+
+       /** @var boolean True, if ALL entries should get shown */
+       protected static $showAll;
+       /** @var int The determined start item of the current page */
+       protected static $firstItemNum;
+
+       /**
+        * Collects all notifications from the backend
+        *
+        * @return array The determined notification array
+        *               ['header', 'notifications']
+        */
+       abstract public static function getNotifications();
+
+       public static function init(array $parameters = [])
+       {
+               if (!local_user()) {
+                       throw new ForbiddenException(DI::l10n()->t('Permission denied.'));
+               }
+
+               $page = ($_REQUEST['page'] ?? 0) ?: 1;
+
+               self::$firstItemNum = ($page * self::ITEMS_PER_PAGE) - self::ITEMS_PER_PAGE;
+               self::$showAll      = ($_REQUEST['show'] ?? '') === 'all';
+       }
+
+       public static function post(array $parameters = [])
+       {
+               $request_id = DI::args()->get(1);
+
+               if ($request_id === 'all') {
+                       return;
+               }
+
+               if ($request_id) {
+                       $intro = DI::intro()->selectFirst(['id' => $request_id, 'uid' => local_user()]);
+
+                       switch ($_POST['submit']) {
+                               case DI::l10n()->t('Discard'):
+                                       $intro->discard();
+                                       break;
+                               case DI::l10n()->t('Ignore'):
+                                       $intro->ignore();
+                                       break;
+                       }
+
+                       DI::baseUrl()->redirect('notifications/intros');
+               }
+       }
+
+       public static function rawContent(array $parameters = [])
+       {
+               // If the last argument of the query is NOT json, return
+               if (DI::args()->get(DI::args()->getArgc() - 1) !== 'json') {
+                       return;
+               }
+
+               // Set the pager
+               $pager = new Pager(DI::args()->getQueryString(), self::ITEMS_PER_PAGE);
+
+               // Add additional informations (needed for json output)
+               $notifications = [
+                       'notifications' => static::getNotifications(),
+                       'items_page'    => $pager->getItemsPerPage(),
+                       'page'          => $pager->getPage(),
+               ];
+
+               System::jsonExit($notifications);
+       }
+
+       /**
+        * Shows the printable result of notifications for a specific tab
+        *
+        * @param string $header        The notification header
+        * @param array  $notifications The array with the notifications
+        * @param string $noContent     The string in case there are no notifications
+        * @param array  $showLink      The possible links at the top
+        *
+        * @return string The rendered output
+        *
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        */
+       protected static function printContent(string $header, array $notifications, string $noContent, array $showLink)
+       {
+               // Get the nav tabs for the notification pages
+               $tabs = self::getTabs();
+
+               // Set the pager
+               $pager = new Pager(DI::args()->getQueryString(), self::ITEMS_PER_PAGE);
+
+               $notif_tpl = Renderer::getMarkupTemplate('notifications/notifications.tpl');
+               return Renderer::replaceMacros($notif_tpl, [
+                       '$header'        => $header ?? DI::l10n()->t('Notifications'),
+                       '$tabs'          => $tabs,
+                       '$notifications' => $notifications,
+                       '$noContent'     => $noContent,
+                       '$showLink'      => $showLink,
+                       '$paginate'      => $pager->renderMinimal(count($notifications))
+               ]);
+       }
+
+       /**
+        * List of pages for the Notifications TabBar
+        *
+        * @return array with with notifications TabBar data
+        * @throws Exception
+        */
+       private static function getTabs()
+       {
+               $selected = DI::args()->get(1, '');
+
+               $tabs = [];
+
+               foreach (self::URL_TYPES as $type => $url) {
+                       $tabs[] = [
+                               'label'     => DI::l10n()->t(self::PRINT_TYPES[$type]),
+                               'url'       => 'notifications/' . $url,
+                               'sel'       => (($selected == $url) ? 'active' : ''),
+                               'id'        => $type . '-tab',
+                               'accesskey' => self::ACCESS_KEYS[$type],
+                       ];
+               }
+
+               return $tabs;
+       }
+}
diff --git a/src/Module/BaseProfile.php b/src/Module/BaseProfile.php
new file mode 100644 (file)
index 0000000..b5461d3
--- /dev/null
@@ -0,0 +1,129 @@
+<?php
+
+namespace Friendica\Module;
+
+use Friendica\App;
+use Friendica\BaseModule;
+use Friendica\Core\Hook;
+use Friendica\Core\Renderer;
+use Friendica\DI;
+
+class BaseProfile extends BaseModule
+{
+       /**
+        * Returns the HTML for the profile pages tabs
+        *
+        * @param App    $a
+        * @param string $current
+        * @param bool   $is_owner
+        * @param string $nickname
+        * @return string
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        */
+       public static function getTabsHTML(App $a, string $current, bool $is_owner, string $nickname = null)
+       {
+               if (is_null($nickname)) {
+                       $nickname = $a->user['nickname'];
+               }
+
+               $baseProfileUrl = DI::baseUrl() . '/profile/' . $nickname;
+
+               $tabs = [
+                       [
+                               'label' => DI::l10n()->t('Profile'),
+                               'url'   => $baseProfileUrl . '/profile',
+                               'sel'   => $current == 'profile' ? 'active' : '',
+                               'title' => DI::l10n()->t('Profile Details'),
+                               'id'    => 'profile-tab',
+                               'accesskey' => 'r',
+                       ],
+                       [
+                               'label' => DI::l10n()->t('Status'),
+                               'url'   => $baseProfileUrl . '/status',
+                               'sel'   => $current == 'status' ? 'active' : '',
+                               'title' => DI::l10n()->t('Status Messages and Posts'),
+                               'id'    => 'status-tab',
+                               'accesskey' => 'm',
+                       ],
+                       [
+                               'label' => DI::l10n()->t('Photos'),
+                               'url'   => DI::baseUrl() . '/photos/' . $nickname,
+                               'sel'   => $current == 'photos' ? 'active' : '',
+                               'title' => DI::l10n()->t('Photo Albums'),
+                               'id'    => 'photo-tab',
+                               'accesskey' => 'h',
+                       ],
+                       [
+                               'label' => DI::l10n()->t('Videos'),
+                               'url'   => DI::baseUrl() . '/videos/' . $nickname,
+                               'sel'   => $current == 'videos' ? 'active' : '',
+                               'title' => DI::l10n()->t('Videos'),
+                               'id'    => 'video-tab',
+                               'accesskey' => 'v',
+                       ],
+               ];
+
+               // the calendar link for the full featured events calendar
+               if ($is_owner && $a->theme_events_in_profile) {
+                       $tabs[] = [
+                               'label' => DI::l10n()->t('Events'),
+                               'url'   => DI::baseUrl() . '/events',
+                               'sel'   => $current == 'events' ? 'active' : '',
+                               'title' => DI::l10n()->t('Events and Calendar'),
+                               'id'    => 'events-tab',
+                               'accesskey' => 'e',
+                       ];
+                       // if the user is not the owner of the calendar we only show a calendar
+                       // with the public events of the calendar owner
+               } elseif (!$is_owner) {
+                       $tabs[] = [
+                               'label' => DI::l10n()->t('Events'),
+                               'url'   => DI::baseUrl() . '/cal/' . $nickname,
+                               'sel'   => $current == 'cal' ? 'active' : '',
+                               'title' => DI::l10n()->t('Events and Calendar'),
+                               'id'    => 'events-tab',
+                               'accesskey' => 'e',
+                       ];
+               }
+
+               if ($is_owner) {
+                       $tabs[] = [
+                               'label' => DI::l10n()->t('Personal Notes'),
+                               'url'   => DI::baseUrl() . '/notes',
+                               'sel'   => $current == 'notes' ? 'active' : '',
+                               'title' => DI::l10n()->t('Only You Can See This'),
+                               'id'    => 'notes-tab',
+                               'accesskey' => 't',
+                       ];
+               }
+
+               if (empty($a->profile['hide-friends'])) {
+                       $tabs[] = [
+                               'label' => DI::l10n()->t('Contacts'),
+                               'url'   => $baseProfileUrl . '/contacts',
+                               'sel'   => $current == 'contacts' ? 'active' : '',
+                               'title' => DI::l10n()->t('Contacts'),
+                               'id'    => 'viewcontacts-tab',
+                               'accesskey' => 'k',
+                       ];
+               }
+
+               if (DI::session()->get('new_member') && $is_owner) {
+                       $tabs[] = [
+                               'label' => DI::l10n()->t('Tips for New Members'),
+                               'url'   => DI::baseUrl() . '/newmember',
+                               'sel'   => false,
+                               'title' => DI::l10n()->t('Tips for New Members'),
+                               'id'    => 'newmember-tab',
+                       ];
+               }
+
+               $arr = ['is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => $current, 'tabs' => $tabs];
+
+               Hook::callAll('profile_tabs', $arr);
+
+               $tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
+
+               return Renderer::replaceMacros($tpl, ['$tabs' => $arr['tabs']]);
+       }
+}
index 2f51dde6459d8571ac51bfc77d6c1e07a947ad41..225f5ed4aefb09ddb55e907f34c3793eb759b062 100644 (file)
@@ -35,9 +35,9 @@ class BaseSettingsModule extends BaseModule
                ];
 
                $tabs[] = [
-                       'label' => DI::l10n()->t('Profiles'),
-                       'url' => 'profiles',
-                       'selected' => (($a->argc == 1) && ($a->argv[0] === 'profiles') ? 'active' : ''),
+                       'label' => DI::l10n()->t('Profile'),
+                       'url' => 'settings/profile',
+                       'selected' => (($a->argc > 1) && ($a->argv[1] === 'profile') ? 'active' : ''),
                        'accesskey' => 'p',
                ];
 
index 6549dd1e0f3eaf105f00dce9eec247d454b8e794..1cb0132a0ea2fddd6a8131c9a31e068c725d7fa3 100644 (file)
@@ -100,14 +100,6 @@ class Contact extends BaseModule
 
                Hook::callAll('contact_edit_post', $_POST);
 
-               $profile_id = intval($_POST['profile-assign'] ?? 0);
-               if ($profile_id) {
-                       if (!DBA::exists('profile', ['id' => $profile_id, 'uid' => local_user()])) {
-                               notice(DI::l10n()->t('Could not locate selected profile.') . EOL);
-                               return;
-                       }
-               }
-
                $hidden = !empty($_POST['hidden']);
 
                $notify = !empty($_POST['notify']);
@@ -124,7 +116,6 @@ class Contact extends BaseModule
                $info = Strings::escapeHtml(trim($_POST['info'] ?? ''));
 
                $r = DBA::update('contact', [
-                       'profile-id' => $profile_id,
                        'priority'   => $priority,
                        'info'       => $info,
                        'hidden'     => $hidden,
@@ -245,8 +236,10 @@ class Contact extends BaseModule
 
                $a = DI::app();
 
-               $nets = $_GET['nets'] ?? '';
-               $rel  = $_GET['rel']  ?? '';
+               $search = Strings::escapeTags(trim($_GET['search'] ?? ''));
+               $nets   = Strings::escapeTags(trim($_GET['nets']   ?? ''));
+               $rel    = Strings::escapeTags(trim($_GET['rel']    ?? ''));
+               $group  = Strings::escapeTags(trim($_GET['group']  ?? ''));
 
                if (empty(DI::page()['aside'])) {
                        DI::page()['aside'] = '';
@@ -324,6 +317,12 @@ class Contact extends BaseModule
                        $follow_widget = '';
                        $networks_widget = '';
                        $rel_widget = '';
+
+                       if ($contact['uid'] != 0) {
+                               $groups_widget = Model\Group::sidebarWidget('contact', 'group', 'full', 'everyone', $contact_id);
+                       } else {
+                               $groups_widget = '';
+                       }
                } else {
                        $vcard_widget = '';
                        $findpeople_widget = Widget::findPeople();
@@ -335,12 +334,7 @@ class Contact extends BaseModule
 
                        $networks_widget = Widget::networks($_SERVER['REQUEST_URI'], $nets);
                        $rel_widget = Widget::contactRels($_SERVER['REQUEST_URI'], $rel);
-               }
-
-               if ($contact['uid'] != 0) {
-                       $groups_widget = Model\Group::sidebarWidget('contact', 'group', 'full', 'everyone', $contact_id);
-               } else {
-                       $groups_widget = null;
+                       $groups_widget = Widget::groups($_SERVER['REQUEST_URI'], $group);
                }
 
                DI::page()['aside'] .= $vcard_widget . $findpeople_widget . $follow_widget . $groups_widget . $networks_widget . $rel_widget;
@@ -350,7 +344,6 @@ class Contact extends BaseModule
                        '$baseurl' => DI::baseUrl()->get(true),
                ]);
 
-               $sort_type = 0;
                $o = '';
                Nav::setSelected('contact');
 
@@ -553,20 +546,13 @@ class Contact extends BaseModule
                                $poll_interval = ContactSelector::pollInterval($contact['priority'], !$poll_enabled);
                        }
 
-                       $profile_select = null;
-                       if ($contact['network'] == Protocol::DFRN) {
-                               $profile_select = ContactSelector::profileAssign($contact['profile-id'], $contact['network'] !== Protocol::DFRN);
-                       }
-
                        // Load contactact related actions like hide, suggest, delete and others
                        $contact_actions = self::getContactActions($contact);
 
                        if ($contact['uid'] != 0) {
-                               $lbl_vis1 = DI::l10n()->t('Profile Visibility');
                                $lbl_info1 = DI::l10n()->t('Contact Information / Notes');
                                $contact_settings_label = DI::l10n()->t('Contact Settings');
                        } else {
-                               $lbl_vis1 = null;
                                $lbl_info1 = null;
                                $contact_settings_label = null;
                        }
@@ -576,8 +562,6 @@ class Contact extends BaseModule
                                '$header'         => DI::l10n()->t('Contact'),
                                '$tab_str'        => $tab_str,
                                '$submit'         => DI::l10n()->t('Submit'),
-                               '$lbl_vis1'       => $lbl_vis1,
-                               '$lbl_vis2'       => DI::l10n()->t('Please choose the profile you would like to display to %s when viewing your profile securely.', $contact['name']),
                                '$lbl_info1'      => $lbl_info1,
                                '$lbl_info2'      => DI::l10n()->t('Their personal note'),
                                '$reason'         => trim(Strings::escapeTags($contact['reason'])),
@@ -598,7 +582,6 @@ class Contact extends BaseModule
                                '$updpub'         => DI::l10n()->t('Update public posts'),
                                '$last_update'    => $last_update,
                                '$udnow'          => DI::l10n()->t('Update now'),
-                               '$profile_select' => $profile_select,
                                '$contact_id'     => $contact['id'],
                                '$block_text'     => ($contact['blocked'] ? DI::l10n()->t('Unblock') : DI::l10n()->t('Block')),
                                '$ignore_text'    => ($contact['readonly'] ? DI::l10n()->t('Unignore') : DI::l10n()->t('Ignore')),
@@ -643,39 +626,116 @@ class Contact extends BaseModule
                        return $arr['output'];
                }
 
-               $select_uid = local_user();
+               $sql_values = [local_user()];
 
                // @TODO: Replace with parameter from router
                $type = $a->argv[1] ?? '';
 
                switch ($type) {
                        case 'blocked':
-                               $sql_extra = sprintf(" AND EXISTS(SELECT `id` from `user-contact` WHERE `contact`.`id` = `user-contact`.`cid` and `user-contact`.`uid` = %d and `user-contact`.`blocked`)", intval(local_user()));
-                               $select_uid = 0;
+                               $sql_extra = " AND EXISTS(SELECT `id` from `user-contact` WHERE `contact`.`id` = `user-contact`.`cid` and `user-contact`.`uid` = ? and `user-contact`.`blocked`)";
+                               // This makes the query look for contact.uid = 0
+                               array_unshift($sql_values, 0);
                                break;
                        case 'hidden':
                                $sql_extra = " AND `hidden` AND NOT `blocked` AND NOT `pending`";
                                break;
                        case 'ignored':
-                               $sql_extra = sprintf(" AND EXISTS(SELECT `id` from `user-contact` WHERE `contact`.`id` = `user-contact`.`cid` and `user-contact`.`uid` = %d and `user-contact`.`ignored`)", intval(local_user()));
-                               $select_uid = 0;
+                               $sql_extra = " AND EXISTS(SELECT `id` from `user-contact` WHERE `contact`.`id` = `user-contact`.`cid` and `user-contact`.`uid` = ? and `user-contact`.`ignored`)";
+                               // This makes the query look for contact.uid = 0
+                               array_unshift($sql_values, 0);
                                break;
                        case 'archived':
                                $sql_extra = " AND `archive` AND NOT `blocked` AND NOT `pending`";
                                break;
                        case 'pending':
-                               $sql_extra = sprintf(" AND `pending` AND NOT `archive` AND ((`rel` = %d)
-                                       OR EXISTS (SELECT `id` FROM `intro` WHERE `contact-id` = `contact`.`id` AND NOT `ignore`))", Model\Contact::SHARING);
+                               $sql_extra = " AND `pending` AND NOT `archive` AND ((`rel` = ?)
+                                       OR EXISTS (SELECT `id` FROM `intro` WHERE `contact-id` = `contact`.`id` AND NOT `ignore`))";
+                               $sql_values[] = Model\Contact::SHARING;
                                break;
                        default:
                                $sql_extra = " AND NOT `archive` AND NOT `blocked` AND NOT `pending`";
+                               break;
+               }
+
+               $searching = false;
+               $search_hdr = null;
+               if ($search) {
+                       $searching = true;
+                       $search_hdr = $search;
+                       $search_txt = preg_quote($search);
+                       $sql_extra .= " AND (name REGEXP ? OR url REGEXP ? OR nick REGEXP ?)";
+                       $sql_values[] = $search_txt;
+                       $sql_values[] = $search_txt;
+                       $sql_values[] = $search_txt;
                }
 
-               $sql_extra .= sprintf(" AND `network` != '%s' ", Protocol::PHANTOM);
+               if ($nets) {
+                       $sql_extra .= " AND network = ? ";
+                       $sql_values[] = $nets;
+               }
 
-               $search = Strings::escapeTags(trim($_GET['search'] ?? ''));
-               $nets   = Strings::escapeTags(trim($_GET['nets']   ?? ''));
-               $rel    = Strings::escapeTags(trim($_GET['rel']    ?? ''));
+               switch ($rel) {
+                       case 'followers':
+                               $sql_extra .= " AND `rel` IN (?, ?)";
+                               $sql_values[] = Model\Contact::FOLLOWER;
+                               $sql_values[] = Model\Contact::FRIEND;
+                               break;
+                       case 'following':
+                               $sql_extra .= " AND `rel` IN (?, ?)";
+                               $sql_values[] = Model\Contact::SHARING;
+                               $sql_values[] = Model\Contact::FRIEND;
+                               break;
+                       case 'mutuals':
+                               $sql_extra .= " AND `rel` = ?";
+                               $sql_values[] = Model\Contact::FRIEND;
+                               break;
+               }
+
+               if ($group) {
+                       $sql_extra = " AND EXISTS(SELECT `id` FROM `group_member` WHERE `gid` = ? AND `contact`.`id` = `contact-id`)";
+                       $sql_values[] = $group;
+               }
+
+               $sql_extra .= Widget::unavailableNetworks();
+
+               $total = 0;
+               $stmt = DBA::p("SELECT COUNT(*) AS `total`
+                       FROM `contact`
+                       WHERE `uid` = ?
+                       AND `self` = 0
+                       AND NOT `deleted`
+                       $sql_extra",
+                       $sql_values
+               );
+               if (DBA::isResult($stmt)) {
+                       $total = DBA::fetch($stmt)['total'];
+               }
+               DBA::close($stmt);
+
+               $pager = new Pager(DI::args()->getQueryString());
+
+               $sql_values[] = $pager->getStart();
+               $sql_values[] = $pager->getItemsPerPage();
+
+               $contacts = [];
+
+               $stmt = DBA::p("SELECT *
+                       FROM `contact`
+                       WHERE `uid` = ?
+                       AND `self` = 0
+                       AND NOT `deleted`
+                       $sql_extra
+                       ORDER BY `name` ASC
+                       LIMIT ?, ?",
+                       $sql_values
+               );
+               while ($contact = DBA::fetch($stmt)) {
+                       $contact['blocked'] = Model\Contact::isBlockedByUser($contact['id'], local_user());
+                       $contact['readonly'] = Model\Contact::isIgnoredByUser($contact['id'], local_user());
+                       $contacts[] = self::getContactTemplateVars($contact);
+               }
+               DBA::close($stmt);
 
                $tabs = [
                        [
@@ -736,58 +796,8 @@ class Contact extends BaseModule
                        ],
                ];
 
-               $tab_tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
-               $t = Renderer::replaceMacros($tab_tpl, ['$tabs' => $tabs]);
-
-               $total = 0;
-               $searching = false;
-               $search_hdr = null;
-               if ($search) {
-                       $searching = true;
-                       $search_hdr = $search;
-                       $search_txt = DBA::escape(Strings::protectSprintf(preg_quote($search)));
-                       $sql_extra .= " AND (name REGEXP '$search_txt' OR url REGEXP '$search_txt'  OR nick REGEXP '$search_txt') ";
-               }
-
-               if ($nets) {
-                       $sql_extra .= sprintf(" AND network = '%s' ", DBA::escape($nets));
-               }
-
-               switch ($rel) {
-                       case 'followers': $sql_extra .= " AND `rel` IN (1, 3)"; break;
-                       case 'following': $sql_extra .= " AND `rel` IN (2, 3)"; break;
-                       case 'mutuals': $sql_extra .= " AND `rel` = 3"; break;
-               }
-
-               $sql_extra .=  " AND NOT `deleted` ";
-
-               $sql_extra2 = ((($sort_type > 0) && ($sort_type <= Model\Contact::FRIEND)) ? sprintf(" AND `rel` = %d ", intval($sort_type)) : '');
-
-               $sql_extra3 = Widget::unavailableNetworks();
-
-               $r = q("SELECT COUNT(*) AS `total` FROM `contact`
-                       WHERE `uid` = %d AND `self` = 0 $sql_extra $sql_extra2 $sql_extra3",
-                       intval($select_uid)
-               );
-               if (DBA::isResult($r)) {
-                       $total = $r[0]['total'];
-               }
-               $pager = new Pager(DI::args()->getQueryString());
-
-               $contacts = [];
-
-               $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 $sql_extra $sql_extra2 $sql_extra3 ORDER BY `name` ASC LIMIT %d , %d ",
-                       intval($select_uid),
-                       $pager->getStart(),
-                       $pager->getItemsPerPage()
-               );
-               if (DBA::isResult($r)) {
-                       foreach ($r as $rr) {
-                               $rr['blocked'] = Model\Contact::isBlockedByUser($rr['id'], local_user());
-                               $rr['readonly'] = Model\Contact::isIgnoredByUser($rr['id'], local_user());
-                               $contacts[] = self::getContactTemplateVars($rr);
-                       }
-               }
+               $tabs_tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
+               $tabs_html = Renderer::replaceMacros($tabs_tpl, ['$tabs' => $tabs]);
 
                switch ($rel) {
                        case 'followers': $header = DI::l10n()->t('Followers'); break;
@@ -809,7 +819,7 @@ class Contact extends BaseModule
                $tpl = Renderer::getMarkupTemplate('contacts-template.tpl');
                $o .= Renderer::replaceMacros($tpl, [
                        '$header'     => $header,
-                       '$tabs'       => $t,
+                       '$tabs'       => $tabs_html,
                        '$total'      => $total,
                        '$search'     => $search_hdr,
                        '$desc'       => DI::l10n()->t('Search your contacts'),
diff --git a/src/Module/Notifications/Introductions.php b/src/Module/Notifications/Introductions.php
new file mode 100644 (file)
index 0000000..10919a1
--- /dev/null
@@ -0,0 +1,199 @@
+<?php
+
+namespace Friendica\Module\Notifications;
+
+use Friendica\Content\ContactSelector;
+use Friendica\Content\Nav;
+use Friendica\Core\Protocol;
+use Friendica\Core\Renderer;
+use Friendica\Database\DBA;
+use Friendica\DI;
+use Friendica\Module\BaseNotifications;
+use Friendica\Object\Notification\Introduction;
+
+/**
+ * Prints notifications about introduction
+ */
+class Introductions extends BaseNotifications
+{
+       /**
+        * @inheritDoc
+        */
+       public static function getNotifications()
+       {
+               $id  = (int)DI::args()->get(2, 0);
+               $all = DI::args()->get(2) == 'all';
+
+               $notifications = [
+                       'ident'         => 'introductions',
+                       'notifications' => DI::notificationIntro()->getList($all, self::$firstItemNum, self::ITEMS_PER_PAGE, $id),
+               ];
+
+               return [
+                       'header'        => DI::l10n()->t('Notifications'),
+                       'notifications' => $notifications,
+               ];
+       }
+
+       public static function content(array $parameters = [])
+       {
+               Nav::setSelected('introductions');
+
+               $all = DI::args()->get(2) == 'all';
+
+               $notificationContent   = [];
+               $notificationNoContent = '';
+
+               $notificationResult = self::getNotifications();
+               $notifications      = $notificationResult['notifications'] ?? [];
+               $notificationHeader = $notificationResult['header'] ?? '';
+
+               $notificationSuggestions = Renderer::getMarkupTemplate('notifications/suggestions.tpl');
+               $notificationTemplate    = Renderer::getMarkupTemplate('notifications/intros.tpl');
+
+               // The link to switch between ignored and normal connection requests
+               $notificationShowLink = [
+                       'href' => (!$all ? 'notifications/intros/all' : 'notifications/intros'),
+                       'text' => (!$all ? DI::l10n()->t('Show Ignored Requests') : DI::l10n()->t('Hide Ignored Requests')),
+               ];
+
+               // Loop through all introduction notifications.This creates an array with the output html for each
+               // introduction
+               /** @var Introduction $notification */
+               foreach ($notifications['notifications'] as $notification) {
+
+                       // There are two kind of introduction. Contacts suggested by other contacts and normal connection requests.
+                       // We have to distinguish between these two because they use different data.
+                       switch ($notification->getLabel()) {
+                               case 'friend_suggestion':
+                                       $notificationContent[] = Renderer::replaceMacros($notificationSuggestions, [
+                                               '$type'                  => $notification->getLabel(),
+                                               '$str_notification_type' => DI::l10n()->t('Notification type:'),
+                                               '$str_type'              => $notification->getType(),
+                                               '$intro_id'              => $notification->getIntroId(),
+                                               '$lbl_madeby'            => DI::l10n()->t('Suggested by:'),
+                                               '$madeby'                => $notification->getMadeBy(),
+                                               '$madeby_url'            => $notification->getMadeByUrl(),
+                                               '$madeby_zrl'            => $notification->getMadeByZrl(),
+                                               '$madeby_addr'           => $notification->getMadeByAddr(),
+                                               '$contact_id'            => $notification->getContactId(),
+                                               '$photo'                 => $notification->getPhoto(),
+                                               '$fullname'              => $notification->getName(),
+                                               '$url'                   => $notification->getUrl(),
+                                               '$zrl'                   => $notification->getZrl(),
+                                               '$lbl_url'               => DI::l10n()->t('Profile URL'),
+                                               '$addr'                  => $notification->getAddr(),
+                                               '$hidden'                => ['hidden', DI::l10n()->t('Hide this contact from others'), $notification->isHidden(), ''],
+                                               '$knowyou'               => $notification->getKnowYou(),
+                                               '$approve'               => DI::l10n()->t('Approve'),
+                                               '$note'                  => $notification->getNote(),
+                                               '$request'               => $notification->getRequest(),
+                                               '$ignore'                => DI::l10n()->t('Ignore'),
+                                               '$discard'               => DI::l10n()->t('Discard'),
+                                       ]);
+                                       break;
+
+                               // Normal connection requests
+                               default:
+                                       $friend_selected = (($notification->getNetwork() !== Protocol::OSTATUS) ? ' checked="checked" ' : ' disabled ');
+                                       $fan_selected    = (($notification->getNetwork() === Protocol::OSTATUS) ? ' checked="checked" disabled ' : '');
+
+                                       $lbl_knowyou = '';
+                                       $knowyou     = '';
+                                       $helptext    = '';
+                                       $helptext2   = '';
+                                       $helptext3   = '';
+
+                                       if ($notification->getNetwork() === Protocol::DFRN) {
+                                               $lbl_knowyou = DI::l10n()->t('Claims to be known to you: ');
+                                               $knowyou     = ($notification->getKnowYou() ? DI::l10n()->t('yes') : DI::l10n()->t('no'));
+                                               $helptext    = DI::l10n()->t('Shall your connection be bidirectional or not?');
+                                               $helptext2   = DI::l10n()->t('Accepting %s as a friend allows %s to subscribe to your posts, and you will also receive updates from them in your news feed.', $notification->getName(), $notification->getName());
+                                               $helptext3   = DI::l10n()->t('Accepting %s as a subscriber allows them to subscribe to your posts, but you will not receive updates from them in your news feed.', $notification->getName());
+                                       } elseif ($notification->getNetwork() === Protocol::DIASPORA) {
+                                               $helptext  = DI::l10n()->t('Shall your connection be bidirectional or not?');
+                                               $helptext2 = DI::l10n()->t('Accepting %s as a friend allows %s to subscribe to your posts, and you will also receive updates from them in your news feed.', $notification->getName(), $notification->getName());
+                                               $helptext3 = DI::l10n()->t('Accepting %s as a sharer allows them to subscribe to your posts, but you will not receive updates from them in your news feed.', $notification->getName());
+                                       }
+
+                                       $dfrn_tpl  = Renderer::getMarkupTemplate('notifications/netfriend.tpl');
+                                       $dfrn_text = Renderer::replaceMacros($dfrn_tpl, [
+                                               '$intro_id'        => $notification->getIntroId(),
+                                               '$friend_selected' => $friend_selected,
+                                               '$fan_selected'    => $fan_selected,
+                                               '$approve_as1'     => $helptext,
+                                               '$approve_as2'     => $helptext2,
+                                               '$approve_as3'     => $helptext3,
+                                               '$as_friend'       => DI::l10n()->t('Friend'),
+                                               '$as_fan'          => (($notification->getNetwork() == Protocol::DIASPORA) ? DI::l10n()->t('Sharer') : DI::l10n()->t('Subscriber')),
+                                       ]);
+
+                                       $contact = DBA::selectFirst('contact', ['network', 'protocol'], ['id' => $notification->getContactId()]);
+
+                                       if (($contact['network'] != Protocol::DFRN) || ($contact['protocol'] == Protocol::ACTIVITYPUB)) {
+                                               $action = 'follow_confirm';
+                                       } else {
+                                               $action = 'dfrn_confirm';
+                                       }
+
+                                       $header = $notification->getName();
+
+                                       if ($notification->getAddr() != '') {
+                                               $header .= ' <' . $notification->getAddr() . '>';
+                                       }
+
+                                       $header .= ' (' . ContactSelector::networkToName($notification->getNetwork(), $notification->getUrl()) . ')';
+
+                                       if ($notification->getNetwork() != Protocol::DIASPORA) {
+                                               $discard = DI::l10n()->t('Discard');
+                                       } else {
+                                               $discard = '';
+                                       }
+
+                                       $notificationContent[] = Renderer::replaceMacros($notificationTemplate, [
+                                               '$type'                  => $notification->getLabel(),
+                                               '$header'                => $header,
+                                               '$str_notification_type' => DI::l10n()->t('Notification type:'),
+                                               '$str_type'              => $notification->getType(),
+                                               '$dfrn_text'             => $dfrn_text,
+                                               '$dfrn_id'               => $notification->getDfrnId(),
+                                               '$uid'                   => $notification->getUid(),
+                                               '$intro_id'              => $notification->getIntroId(),
+                                               '$contact_id'            => $notification->getContactId(),
+                                               '$photo'                 => $notification->getPhoto(),
+                                               '$fullname'              => $notification->getName(),
+                                               '$location'              => $notification->getLocation(),
+                                               '$lbl_location'          => DI::l10n()->t('Location:'),
+                                               '$about'                 => $notification->getAbout(),
+                                               '$lbl_about'             => DI::l10n()->t('About:'),
+                                               '$keywords'              => $notification->getKeywords(),
+                                               '$lbl_keywords'          => DI::l10n()->t('Tags:'),
+                                               '$gender'                => $notification->getGender(),
+                                               '$lbl_gender'            => DI::l10n()->t('Gender:'),
+                                               '$hidden'                => ['hidden', DI::l10n()->t('Hide this contact from others'), $notification->isHidden(), ''],
+                                               '$url'                   => $notification->getUrl(),
+                                               '$zrl'                   => $notification->getZrl(),
+                                               '$lbl_url'               => DI::l10n()->t('Profile URL'),
+                                               '$addr'                  => $notification->getAddr(),
+                                               '$lbl_knowyou'           => $lbl_knowyou,
+                                               '$lbl_network'           => DI::l10n()->t('Network:'),
+                                               '$network'               => ContactSelector::networkToName($notification->getNetwork(), $notification->getUrl()),
+                                               '$knowyou'               => $knowyou,
+                                               '$approve'               => DI::l10n()->t('Approve'),
+                                               '$note'                  => $notification->getNote(),
+                                               '$ignore'                => DI::l10n()->t('Ignore'),
+                                               '$discard'               => $discard,
+                                               '$action'                => $action,
+                                       ]);
+                                       break;
+                       }
+               }
+
+               if (count($notifications['notifications']) == 0) {
+                       info(DI::l10n()->t('No introductions.') . EOL);
+                       $notificationNoContent = DI::l10n()->t('No more %s notifications.', $notifications['ident']);
+               }
+
+               return self::printContent($notificationHeader, $notificationContent, $notificationNoContent, $notificationShowLink);
+       }
+}
diff --git a/src/Module/Notifications/Notification.php b/src/Module/Notifications/Notification.php
new file mode 100644 (file)
index 0000000..9b25256
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+namespace Friendica\Module\Notifications;
+
+use Friendica\BaseModule;
+use Friendica\Core\System;
+use Friendica\DI;
+use Friendica\Network\HTTPException;
+
+/**
+ * Interacting with the /notification command
+ */
+class Notification extends BaseModule
+{
+       public static function init(array $parameters = [])
+       {
+               if (!local_user()) {
+                       throw new HTTPException\UnauthorizedException(DI::l10n()->t('Permission denied.'));
+               }
+       }
+
+       public static function rawContent(array $parameters = [])
+       {
+               // @TODO: Replace with parameter from router
+               if (DI::args()->get(1) === 'mark' && DI::args()->get(2) === 'all') {
+                       try {
+                               $success = DI::notify()->setAllSeen();
+                       }catch (\Exception $e) {
+                               $success = false;
+                       }
+
+                       header('Content-type: application/json; charset=utf-8');
+                       echo json_encode([
+                               'result' => ($success) ? 'success' : 'fail',
+                       ]);
+                       exit();
+               }
+       }
+
+       /**
+        * Redirect to the notifications main page or to the url for the chosen notifications
+        *
+        * @return string|void
+        * @throws HTTPException\InternalServerErrorException
+        */
+       public static function content(array $parameters = [])
+       {
+               // @TODO: Replace with parameter from router
+               if (DI::args()->getArgc() > 2 && DI::args()->get(1) === 'view' && intval(DI::args()->get(2))) {
+                       try {
+                               $notification = DI::notify()->getByID(DI::args()->get(2));
+                               $notification->setSeen();
+
+                               if (!empty($notification->link)) {
+                                       System::externalRedirect($notification->link);
+                               }
+
+                       } catch (HTTPException\NotFoundException $e) {
+                               info(DI::l10n()->t('Invalid notification.'));
+                       }
+
+                       DI::baseUrl()->redirect();
+               }
+
+               // @TODO: Replace with parameter from router
+               DI::baseUrl()->redirect('notifications/system');
+       }
+}
diff --git a/src/Module/Notifications/Notifications.php b/src/Module/Notifications/Notifications.php
new file mode 100644 (file)
index 0000000..37b2346
--- /dev/null
@@ -0,0 +1,124 @@
+<?php
+
+namespace Friendica\Module\Notifications;
+
+use Friendica\Content\Nav;
+use Friendica\Core\Renderer;
+use Friendica\DI;
+use Friendica\Module\BaseNotifications;
+use Friendica\Object\Notification\Notification;
+
+/**
+ * Prints all notification types except introduction:
+ * - Network
+ * - System
+ * - Personal
+ * - Home
+ */
+class Notifications extends BaseNotifications
+{
+       /**
+        * {@inheritDoc}
+        */
+       public static function getNotifications()
+       {
+               $notificationHeader = '';
+               /** @var Notification[] $notifications */
+               $notifications = [];
+
+               // Get the network notifications
+               if ((DI::args()->get(1) == 'network')) {
+                       $notificationHeader = DI::l10n()->t('Network Notifications');
+                       $notifications      = [
+                               'ident'        => Notification::NETWORK,
+                               'notifications' => DI::notification()->getNetworkList(self::$showAll, self::$firstItemNum, self::ITEMS_PER_PAGE),
+                       ];
+
+                       // Get the system notifications
+               } elseif ((DI::args()->get(1) == 'system')) {
+                       $notificationHeader = DI::l10n()->t('System Notifications');
+                       $notifications      = [
+                               'ident'        => Notification::SYSTEM,
+                               'notifications' => DI::notification()->getSystemList(self::$showAll, self::$firstItemNum, self::ITEMS_PER_PAGE),
+                       ];
+
+                       // Get the personal notifications
+               } elseif ((DI::args()->get(1) == 'personal')) {
+                       $notificationHeader = DI::l10n()->t('Personal Notifications');
+                       $notifications      = [
+                               'ident'        => Notification::PERSONAL,
+                               'notifications' => DI::notification()->getPersonalList(self::$showAll, self::$firstItemNum, self::ITEMS_PER_PAGE),
+                       ];
+
+                       // Get the home notifications
+               } elseif ((DI::args()->get(1) == 'home')) {
+                       $notificationHeader = DI::l10n()->t('Home Notifications');
+                       $notifications      = [
+                               'ident'        => Notification::HOME,
+                               'notifications' => DI::notification()->getHomeList(self::$showAll, self::$firstItemNum, self::ITEMS_PER_PAGE),
+                       ];
+                       // fallback - redirect to main page
+               } else {
+                       DI::baseUrl()->redirect('notifications');
+               }
+
+               return [
+                       'header'        => $notificationHeader,
+                       'notifications' => $notifications,
+               ];
+       }
+
+       public static function content(array $parameters = [])
+       {
+               Nav::setSelected('notifications');
+
+               $notificationContent   = [];
+               $notificationNoContent = '';
+
+               $notificationResult = self::getNotifications();
+               $notifications      = $notificationResult['notifications'] ?? [];
+               $notificationHeader = $notificationResult['header'] ?? '';
+
+
+               if (!empty($notifications['notifications'])) {
+                       // Loop trough ever notification This creates an array with the output html for each
+                       // notification and apply the correct template according to the notificationtype (label).
+                       /** @var Notification $notification */
+                       foreach ($notifications['notifications'] as $notification) {
+                               $notification_templates = [
+                                       'like'         => 'notifications/likes_item.tpl',
+                                       'dislike'      => 'notifications/dislikes_item.tpl',
+                                       'attend'       => 'notifications/attend_item.tpl',
+                                       'attendno'     => 'notifications/attend_item.tpl',
+                                       'attendmaybe'  => 'notifications/attend_item.tpl',
+                                       'friend'       => 'notifications/friends_item.tpl',
+                                       'comment'      => 'notifications/comments_item.tpl',
+                                       'post'         => 'notifications/posts_item.tpl',
+                                       'notification' => 'notifications/notification.tpl',
+                               ];
+
+                               $notificationTemplate = Renderer::getMarkupTemplate($notification_templates[$notification->getLabel()]);
+
+                               $notificationContent[] = Renderer::replaceMacros($notificationTemplate, [
+                                       '$item_label' => $notification->getLabel(),
+                                       '$item_link'  => $notification->getLink(),
+                                       '$item_image' => $notification->getImage(),
+                                       '$item_url'   => $notification->getUrl(),
+                                       '$item_text'  => $notification->getText(),
+                                       '$item_when'  => $notification->getWhen(),
+                                       '$item_ago'   => $notification->getAgo(),
+                                       '$item_seen'  => $notification->isSeen(),
+                               ]);
+                       }
+               } else {
+                       $notificationNoContent = DI::l10n()->t('No more %s notifications.', $notifications['ident']);
+               }
+
+               $notificationShowLink = [
+                       'href' => (self::$showAll ? 'notifications/' . $notifications['ident'] : 'notifications/' . $notifications['ident'] . '?show=all'),
+                       'text' => (self::$showAll ? DI::l10n()->t('Show unread') : DI::l10n()->t('Show all')),
+               ];
+
+               return self::printContent($notificationHeader, $notificationContent, $notificationNoContent, $notificationShowLink);
+       }
+}
diff --git a/src/Module/Notifications/Notify.php b/src/Module/Notifications/Notify.php
deleted file mode 100644 (file)
index 3c1b6a0..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-
-namespace Friendica\Module\Notifications;
-
-use Friendica\BaseModule;
-use Friendica\Core\System;
-use Friendica\DI;
-use Friendica\Network\HTTPException;
-
-/**
- * Interacting with the /notify command
- */
-class Notify extends BaseModule
-{
-       public static function init(array $parameters = [])
-       {
-               if (!local_user()) {
-                       throw new HTTPException\UnauthorizedException(DI::l10n()->t('Permission denied.'));
-               }
-       }
-
-       public static function rawContent(array $parameters = [])
-       {
-               $a = DI::app();
-
-               // @TODO: Replace with parameter from router
-               if ($a->argc > 2 && $a->argv[1] === 'mark' && $a->argv[2] === 'all') {
-                       $success              = DI::notify()->setAllSeen();
-
-                       header('Content-type: application/json; charset=utf-8');
-                       echo json_encode([
-                               'result' => ($success) ? 'success' : 'fail',
-                       ]);
-                       exit();
-               }
-       }
-
-       /**
-        * Redirect to the notifications main page or to the url for the chosen notify
-        *
-        * @return string|void
-        * @throws HTTPException\InternalServerErrorException
-        */
-       public static function content(array $parameters = [])
-       {
-               $a = DI::app();
-
-               // @TODO: Replace with parameter from router
-               if ($a->argc > 2 && $a->argv[1] === 'view' && intval($a->argv[2])) {
-                       $notificationsManager = DI::notify();
-                       // @TODO: Replace with parameter from router
-                       $note = $notificationsManager->getByID($a->argv[2]);
-                       if (!empty($note)) {
-                               $notificationsManager->setSeen($note);
-                               if (!empty($note['link'])) {
-                                       System::externalRedirect($note['link']);
-                               }
-                       }
-
-                       DI::baseUrl()->redirect();
-               }
-
-               // @TODO: Replace with parameter from router
-               DI::baseUrl()->redirect('notifications/system');
-       }
-}
diff --git a/src/Module/Profile.php b/src/Module/Profile.php
deleted file mode 100644 (file)
index e3ae7b3..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-<?php
-
-namespace Friendica\Module;
-
-use Friendica\BaseModule;
-use Friendica\Content\Nav;
-use Friendica\Content\Pager;
-use Friendica\Content\Widget;
-use Friendica\Core\ACL;
-use Friendica\Core\Hook;
-use Friendica\Core\Session;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Model\Item;
-use Friendica\Model\Profile as ProfileModel;
-use Friendica\Model\User;
-use Friendica\Module\Security\Login;
-use Friendica\Protocol\ActivityPub;
-use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Security;
-use Friendica\Util\Strings;
-use Friendica\Util\XML;
-
-require_once 'boot.php';
-
-class Profile extends BaseModule
-{
-       public static $which = '';
-       public static $profile = 0;
-
-       public static function init(array $parameters = [])
-       {
-               $a = DI::app();
-
-               // @TODO: Replace with parameter from router
-               if ($a->argc < 2) {
-                       throw new \Friendica\Network\HTTPException\BadRequestException();
-               }
-
-               self::$which = filter_var($a->argv[1], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_BACKTICK);
-
-               // @TODO: Replace with parameter from router
-               if (local_user() && $a->argc > 2 && $a->argv[2] === 'view') {
-                       self::$which = $a->user['nickname'];
-                       self::$profile = filter_var($a->argv[1], FILTER_SANITIZE_NUMBER_INT);
-               }
-       }
-
-       public static function rawContent(array $parameters = [])
-       {
-               if (ActivityPub::isRequest()) {
-                       $user = DBA::selectFirst('user', ['uid'], ['nickname' => self::$which]);
-                       if (DBA::isResult($user)) {
-                               // The function returns an empty array when the account is removed, expired or blocked
-                               $data = ActivityPub\Transmitter::getProfile($user['uid']);
-                               if (!empty($data)) {
-                                       System::jsonExit($data, 'application/activity+json');
-                               }
-                       }
-
-                       if (DBA::exists('userd', ['username' => self::$which])) {
-                               // Known deleted user
-                               $data = ActivityPub\Transmitter::getDeletedUser(self::$which);
-
-                               System::jsonError(410, $data);
-                       } else {
-                               // Any other case (unknown, blocked, unverified, expired, no profile, no self contact)
-                               System::jsonError(404, []);
-                       }
-               }
-       }
-
-       public static function content(array $parameters = [], $update = 0)
-       {
-               $a = DI::app();
-
-               if (!$update) {
-                       ProfileModel::load($a, self::$which, self::$profile);
-
-                       $page = DI::page();
-
-                       $page['htmlhead'] .= "\n";
-
-                       $blocked   = !local_user() && !Session::getRemoteContactID($a->profile['uid']) && DI::config()->get('system', 'block_public');
-                       $userblock = !local_user() && !Session::getRemoteContactID($a->profile['uid']) && $a->profile['hidewall'];
-
-                       if (!empty($a->profile['page-flags']) && $a->profile['page-flags'] == User::PAGE_FLAGS_COMMUNITY) {
-                               $page['htmlhead'] .= '<meta name="friendica.community" content="true" />' . "\n";
-                       }
-
-                       if (!empty($a->profile['openidserver'])) {
-                               $page['htmlhead'] .= '<link rel="openid.server" href="' . $a->profile['openidserver'] . '" />' . "\n";
-                       }
-
-                       if (!empty($a->profile['openid'])) {
-                               $delegate = strstr($a->profile['openid'], '://') ? $a->profile['openid'] : 'https://' . $a->profile['openid'];
-                               $page['htmlhead'] .= '<link rel="openid.delegate" href="' . $delegate . '" />' . "\n";
-                       }
-
-                       // site block
-                       if (!$blocked && !$userblock) {
-                               $keywords = str_replace(['#', ',', ' ', ',,'], ['', ' ', ',', ','], $a->profile['pub_keywords'] ?? '');
-                               if (strlen($keywords)) {
-                                       $page['htmlhead'] .= '<meta name="keywords" content="' . $keywords . '" />' . "\n";
-                               }
-                       }
-
-                       $page['htmlhead'] .= '<meta name="dfrn-global-visibility" content="' . ($a->profile['net-publish'] ? 'true' : 'false') . '" />' . "\n";
-
-                       if (!$a->profile['net-publish'] || $a->profile['hidewall']) {
-                               $page['htmlhead'] .= '<meta content="noindex, noarchive" name="robots" />' . "\n";
-                       }
-
-                       $page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . DI::baseUrl() . '/dfrn_poll/' . self::$which . '" title="DFRN: ' . DI::l10n()->t('%s\'s timeline', $a->profile['username']) . '"/>' . "\n";
-                       $page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . DI::baseUrl() . '/feed/' . self::$which . '/" title="' . DI::l10n()->t('%s\'s posts', $a->profile['username']) . '"/>' . "\n";
-                       $page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . DI::baseUrl() . '/feed/' . self::$which . '/comments" title="' . DI::l10n()->t('%s\'s comments', $a->profile['username']) . '"/>' . "\n";
-                       $page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . DI::baseUrl() . '/feed/' . self::$which . '/activity" title="' . DI::l10n()->t('%s\'s timeline', $a->profile['username']) . '"/>' . "\n";
-                       $uri = urlencode('acct:' . $a->profile['nickname'] . '@' . DI::baseUrl()->getHostname() . (DI::baseUrl()->getUrlPath() ? '/' . DI::baseUrl()->getUrlPath() : ''));
-                       $page['htmlhead'] .= '<link rel="lrdd" type="application/xrd+xml" href="' . DI::baseUrl() . '/xrd/?uri=' . $uri . '" />' . "\n";
-                       header('Link: <' . DI::baseUrl() . '/xrd/?uri=' . $uri . '>; rel="lrdd"; type="application/xrd+xml"', false);
-
-                       $dfrn_pages = ['request', 'confirm', 'notify', 'poll'];
-                       foreach ($dfrn_pages as $dfrn) {
-                               $page['htmlhead'] .= '<link rel="dfrn-' . $dfrn . '" href="' . DI::baseUrl() . '/dfrn_' . $dfrn . '/' . self::$which . '" />' . "\n";
-                       }
-                       $page['htmlhead'] .= '<link rel="dfrn-poco" href="' . DI::baseUrl() . '/poco/' . self::$which . '" />' . "\n";
-               }
-
-               $category = $datequery = $datequery2 = '';
-
-               if ($a->argc > 2) {
-                       for ($x = 2; $x < $a->argc; $x ++) {
-                               if (DI::dtFormat()->isYearMonth($a->argv[$x])) {
-                                       if ($datequery) {
-                                               $datequery2 = Strings::escapeHtml($a->argv[$x]);
-                                       } else {
-                                               $datequery = Strings::escapeHtml($a->argv[$x]);
-                                       }
-                               } else {
-                                       $category = $a->argv[$x];
-                               }
-                       }
-               }
-
-               if (empty($category)) {
-                       $category = $_GET['category'] ?? '';
-               }
-
-               $hashtags = $_GET['tag'] ?? '';
-
-               if (DI::config()->get('system', 'block_public') && !local_user() && !Session::getRemoteContactID($a->profile['uid'])) {
-                       return Login::form();
-               }
-
-               $o = '';
-
-               if ($update) {
-                       // Ensure we've got a profile owner if updating.
-                       $a->profile['uid'] = $update;
-               } elseif ($a->profile['uid'] == local_user()) {
-                       Nav::setSelected('home');
-               }
-
-               $remote_contact = Session::getRemoteContactID($a->profile['uid']);
-               $is_owner = local_user() == $a->profile['uid'];
-               $last_updated_key = "profile:" . $a->profile['uid'] . ":" . local_user() . ":" . $remote_contact;
-
-               if (!empty($a->profile['hidewall']) && !$is_owner && !$remote_contact) {
-                       notice(DI::l10n()->t('Access to this profile has been restricted.') . EOL);
-                       return '';
-               }
-
-               if (!$update) {
-                       $tab = Strings::escapeTags(trim($_GET['tab'] ?? ''));
-
-                       $o .= ProfileModel::getTabs($a, $tab, $is_owner, $a->profile['nickname']);
-
-                       if ($tab === 'profile') {
-                               $o .= ProfileModel::getAdvanced($a);
-                               Hook::callAll('profile_advanced', $o);
-                               return $o;
-                       }
-
-                       $o .= Widget::commonFriendsVisitor($a->profile['uid']);
-
-                       $commpage = $a->profile['page-flags'] == User::PAGE_FLAGS_COMMUNITY;
-                       $commvisitor = $commpage && $remote_contact;
-
-                       DI::page()['aside'] .= Widget::postedByYear(DI::baseUrl()->get(true) . '/profile/' . $a->profile['nickname'], $a->profile['uid'] ?? 0, true);
-                       DI::page()['aside'] .= Widget::categories(DI::baseUrl()->get(true) . '/profile/' . $a->profile['nickname'], XML::escape($category));
-                       DI::page()['aside'] .= Widget::tagCloud();
-
-                       if (Security::canWriteToUserWall($a->profile['uid'])) {
-                               $x = [
-                                       'is_owner' => $is_owner,
-                                       'allow_location' => ($is_owner || $commvisitor) && $a->profile['allow_location'],
-                                       'default_location' => $is_owner ? $a->user['default-location'] : '',
-                                       'nickname' => $a->profile['nickname'],
-                                       'lockstate' => is_array($a->user)
-                                       && (strlen($a->user['allow_cid'])
-                                               || strlen($a->user['allow_gid'])
-                                               || strlen($a->user['deny_cid'])
-                                               || strlen($a->user['deny_gid'])
-                                       ) ? 'lock' : 'unlock',
-                                       'acl' => $is_owner ? ACL::getFullSelectorHTML(DI::page(), $a->user, true) : '',
-                                       'bang' => '',
-                                       'visitor' => $is_owner || $commvisitor ? 'block' : 'none',
-                                       'profile_uid' => $a->profile['uid'],
-                               ];
-
-                               $o .= status_editor($a, $x);
-                       }
-               }
-
-               // Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
-               $sql_extra = Item::getPermissionsSQLByUserId($a->profile['uid']);
-               $sql_extra2 = '';
-
-               $last_updated_array = Session::get('last_updated', []);
-
-               if ($update) {
-                       $last_updated = $last_updated_array[$last_updated_key] ?? 0;
-
-                       // If the page user is the owner of the page we should query for unseen
-                       // items. Otherwise use a timestamp of the last succesful update request.
-                       if ($is_owner || !$last_updated) {
-                               $sql_extra4 = " AND `item`.`unseen`";
-                       } else {
-                               $gmupdate = gmdate(DateTimeFormat::MYSQL, $last_updated);
-                               $sql_extra4 = " AND `item`.`received` > '" . $gmupdate . "'";
-                       }
-
-                       $items_stmt = DBA::p(
-                               "SELECT DISTINCT(`parent-uri`) AS `uri`, `item`.`created`
-                               FROM `item`
-                               INNER JOIN `contact`
-                               ON `contact`.`id` = `item`.`contact-id`
-                                       AND NOT `contact`.`blocked`
-                                       AND NOT `contact`.`pending`
-                               WHERE `item`.`uid` = ?
-                                       AND `item`.`visible`
-                                       AND     (NOT `item`.`deleted` OR `item`.`gravity` = ?)
-                                       AND NOT `item`.`moderated`
-                                       AND `item`.`wall`
-                                       $sql_extra4
-                                       $sql_extra
-                               ORDER BY `item`.`received` DESC",
-                               $a->profile['uid'],
-                               GRAVITY_ACTIVITY
-                       );
-
-                       if (!DBA::isResult($items_stmt)) {
-                               return '';
-                       }
-
-                       $pager = new Pager(DI::args()->getQueryString());
-               } else {
-                       $sql_post_table = "";
-
-                       if (!empty($category)) {
-                               $sql_post_table = sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ",
-                                       DBA::escape(Strings::protectSprintf($category)), intval(TERM_OBJ_POST), intval(TERM_CATEGORY), intval($a->profile['uid']));
-                       }
-
-                       if (!empty($hashtags)) {
-                               $sql_post_table .= sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ",
-                                       DBA::escape(Strings::protectSprintf($hashtags)), intval(TERM_OBJ_POST), intval(TERM_HASHTAG), intval($a->profile['uid']));
-                       }
-
-                       if (!empty($datequery)) {
-                               $sql_extra2 .= Strings::protectSprintf(sprintf(" AND `thread`.`received` <= '%s' ", DBA::escape(DateTimeFormat::convert($datequery, 'UTC', date_default_timezone_get()))));
-                       }
-                       if (!empty($datequery2)) {
-                               $sql_extra2 .= Strings::protectSprintf(sprintf(" AND `thread`.`received` >= '%s' ", DBA::escape(DateTimeFormat::convert($datequery2, 'UTC', date_default_timezone_get()))));
-                       }
-
-                       // Does the profile page belong to a forum?
-                       // If not then we can improve the performance with an additional condition
-                       $condition = ['uid' => $a->profile['uid'], 'page-flags' => [User::PAGE_FLAGS_COMMUNITY, User::PAGE_FLAGS_PRVGROUP]];
-                       if (!DBA::exists('user', $condition)) {
-                               $sql_extra3 = sprintf(" AND `thread`.`contact-id` = %d ", intval(intval($a->profile['contact_id'])));
-                       } else {
-                               $sql_extra3 = "";
-                       }
-
-                       //  check if we serve a mobile device and get the user settings
-                       //  accordingly
-                       if (DI::mode()->isMobile()) {
-                               $itemspage_network = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network', 10);
-                       } else {
-                               $itemspage_network = DI::pConfig()->get(local_user(), 'system', 'itemspage_network', 20);
-                       }
-
-                       //  now that we have the user settings, see if the theme forces
-                       //  a maximum item number which is lower then the user choice
-                       if (($a->force_max_items > 0) && ($a->force_max_items < $itemspage_network)) {
-                               $itemspage_network = $a->force_max_items;
-                       }
-
-                       $pager = new Pager(DI::args()->getQueryString(), $itemspage_network);
-
-                       $pager_sql = sprintf(" LIMIT %d, %d ", $pager->getStart(), $pager->getItemsPerPage());
-
-                       $items_stmt = DBA::p(
-                               "SELECT `item`.`uri`
-                               FROM `thread`
-                               STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
-                               $sql_post_table
-                               STRAIGHT_JOIN `contact`
-                               ON `contact`.`id` = `thread`.`contact-id`
-                                       AND NOT `contact`.`blocked`
-                                       AND NOT `contact`.`pending`
-                               WHERE `thread`.`uid` = ?
-                                       AND `thread`.`visible`
-                                       AND NOT `thread`.`deleted`
-                                       AND NOT `thread`.`moderated`
-                                       AND `thread`.`wall`
-                                       $sql_extra3
-                                       $sql_extra
-                                       $sql_extra2
-                               ORDER BY `thread`.`received` DESC
-                               $pager_sql",
-                               $a->profile['uid']
-                       );
-               }
-
-               // Set a time stamp for this page. We will make use of it when we
-               // search for new items (update routine)
-               $last_updated_array[$last_updated_key] = time();
-               Session::set('last_updated', $last_updated_array);
-
-               if ($is_owner && !$update && !DI::config()->get('theme', 'hide_eventlist')) {
-                       $o .= ProfileModel::getBirthdays();
-                       $o .= ProfileModel::getEventsReminderHTML();
-               }
-
-               if ($is_owner) {
-                       $unseen = Item::exists(['wall' => true, 'unseen' => true, 'uid' => local_user()]);
-                       if ($unseen) {
-                               Item::update(['unseen' => false], ['wall' => true, 'unseen' => true, 'uid' => local_user()]);
-                       }
-               }
-
-               $items = DBA::toArray($items_stmt);
-
-               if ($pager->getStart() == 0 && !empty($a->profile['uid'])) {
-                       $pinned_items = Item::selectPinned($a->profile['uid'], ['uri', 'pinned'], ['true' . $sql_extra]);
-                       $pinned = Item::inArray($pinned_items);
-                       $items = array_merge($items, $pinned);
-               }
-
-               $o .= conversation($a, $items, $pager, 'profile', $update, false, 'pinned_received', $a->profile['uid']);
-
-               if (!$update) {
-                       $o .= $pager->renderMinimal(count($items));
-               }
-
-               return $o;
-       }
-}
index 1a21df0ece64ec9b49b76ac1544c6405534699cc..122681c1708afb34d7b0be2fb1e3e6e031033d67 100644 (file)
@@ -2,7 +2,6 @@
 
 namespace Friendica\Module\Profile;
 
-use Friendica\BaseModule;
 use Friendica\Content\ContactSelector;
 use Friendica\Content\Nav;
 use Friendica\Content\Pager;
@@ -13,9 +12,10 @@ use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Model\Contact;
 use Friendica\Model\Profile;
+use Friendica\Module\BaseProfile;
 use Friendica\Util\Proxy as ProxyUtils;
 
-class Contacts extends BaseModule
+class Contacts extends BaseProfile
 {
        public static function content(array $parameters = [])
        {
@@ -42,8 +42,7 @@ class Contacts extends BaseModule
 
                $is_owner = $a->profile['uid'] == local_user();
 
-               // tabs
-               $o = Profile::getTabs($a, 'contacts', $is_owner, $nickname);
+               $o = self::getTabsHTML($a, 'contacts', $is_owner, $nickname);
 
                if (!count($a->profile) || $a->profile['hide-friends']) {
                        notice(DI::l10n()->t('Permission denied.') . EOL);
diff --git a/src/Module/Profile/Index.php b/src/Module/Profile/Index.php
new file mode 100644 (file)
index 0000000..bf34b02
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+
+namespace Friendica\Module\Profile;
+
+use Friendica\BaseModule;
+
+/**
+ * Profile index router
+ *
+ * The default profile path (https://domain.tld/profile/nickname) has to serve the profile data when queried as an
+ * ActivityPub endpoint, but it should show statuses to web users.
+ *
+ * Both these view have dedicated sub-paths,
+ * respectively https://domain.tld/profile/nickname/profile and https://domain.tld/profile/nickname/status
+ */
+class Index extends BaseModule
+{
+       public static function rawContent(array $parameters = [])
+       {
+               Profile::rawContent($parameters);
+       }
+
+       public static function content(array $parameters = [])
+       {
+               return Status::content($parameters);
+       }
+}
diff --git a/src/Module/Profile/Profile.php b/src/Module/Profile/Profile.php
new file mode 100644 (file)
index 0000000..690f4ee
--- /dev/null
@@ -0,0 +1,297 @@
+<?php
+
+namespace Friendica\Module\Profile;
+
+use Friendica\Content\Feature;
+use Friendica\Content\ForumManager;
+use Friendica\Content\Nav;
+use Friendica\Content\Text\BBCode;
+use Friendica\Content\Text\HTML;
+use Friendica\Core\Hook;
+use Friendica\Core\Protocol;
+use Friendica\Core\Renderer;
+use Friendica\Core\Session;
+use Friendica\Core\System;
+use Friendica\Database\DBA;
+use Friendica\DI;
+use Friendica\Model\Contact;
+use Friendica\Model\Profile as ProfileModel;
+use Friendica\Model\Term;
+use Friendica\Model\User;
+use Friendica\Module\BaseProfile;
+use Friendica\Module\Security\Login;
+use Friendica\Network\HTTPException;
+use Friendica\Protocol\ActivityPub;
+use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Temporal;
+
+class Profile extends BaseProfile
+{
+       public static function rawContent(array $parameters = [])
+       {
+               if (ActivityPub::isRequest()) {
+                       $user = DBA::selectFirst('user', ['uid'], ['nickname' => $parameters['nickname']]);
+                       if (DBA::isResult($user)) {
+                               // The function returns an empty array when the account is removed, expired or blocked
+                               $data = ActivityPub\Transmitter::getProfile($user['uid']);
+                               if (!empty($data)) {
+                                       System::jsonExit($data, 'application/activity+json');
+                               }
+                       }
+
+                       if (DBA::exists('userd', ['username' => $parameters['nickname']])) {
+                               // Known deleted user
+                               $data = ActivityPub\Transmitter::getDeletedUser($parameters['nickname']);
+
+                               System::jsonError(410, $data);
+                       } else {
+                               // Any other case (unknown, blocked, nverified, expired, no profile, no self contact)
+                               System::jsonError(404, []);
+                       }
+               }
+       }
+
+       public static function content(array $parameters = [])
+       {
+               $a = DI::app();
+
+               ProfileModel::load($a, $parameters['nickname']);
+
+               if (!$a->profile) {
+                       throw new HTTPException\NotFoundException(DI::l10n()->t('Profile not found.'));
+               }
+
+               $remote_contact_id = Session::getRemoteContactID($a->profile_uid);
+
+               if (DI::config()->get('system', 'block_public') && !local_user() && !$remote_contact_id) {
+                       return Login::form();
+               }
+
+               $is_owner = local_user() == $a->profile_uid;
+
+               if (!empty($a->profile['hidewall']) && !$is_owner && !$remote_contact_id) {
+                       throw new HTTPException\ForbiddenException(DI::l10n()->t('Access to this profile has been restricted.'));
+               }
+
+               if (!empty($a->profile['page-flags']) && $a->profile['page-flags'] == User::PAGE_FLAGS_COMMUNITY) {
+                       DI::page()['htmlhead'] .= '<meta name="friendica.community" content="true" />' . "\n";
+               }
+
+               DI::page()['htmlhead'] .= self::buildHtmlHead($a->profile, $parameters['nickname'], $remote_contact_id);
+
+               Nav::setSelected('home');
+
+               $is_owner = local_user() == $a->profile['uid'];
+               $o = self::getTabsHTML($a, 'profile', $is_owner, $a->profile['nickname']);
+
+               if (!empty($a->profile['hidewall']) && !$is_owner && !$remote_contact_id) {
+                       notice(DI::l10n()->t('Access to this profile has been restricted.'));
+                       return '';
+               }
+
+               $view_as_contacts = [];
+               $view_as_contact_id = 0;
+               if ($is_owner) {
+                       $view_as_contact_id = intval($_GET['viewas'] ?? 0);
+
+                       $view_as_contacts = Contact::selectToArray(['id', 'name'], [
+                               'uid' => local_user(),
+                               'rel' => [Contact::FOLLOWER, Contact::SHARING, Contact::FRIEND],
+                               'network' => Protocol::DFRN,
+                               'blocked' => false,
+                       ]);
+
+                       // User manually provided a contact ID they aren't privy to, silently defaulting to their own view
+                       if (!in_array($view_as_contact_id, array_column($view_as_contacts, 'id'))) {
+                               $view_as_contact_id = 0;
+                       }
+               }
+
+               $basic_fields = [];
+
+               $basic_fields += self::buildField('fullname', DI::l10n()->t('Full Name:'), $a->profile['name']);
+
+               if (Feature::isEnabled($a->profile_uid, 'profile_membersince')) {
+                       $basic_fields += self::buildField(
+                               'membersince',
+                               DI::l10n()->t('Member since:'),
+                               DateTimeFormat::local($a->profile['register_date'])
+                       );
+               }
+
+               if (!empty($a->profile['dob']) && $a->profile['dob'] > DBA::NULL_DATE) {
+                       $year_bd_format = DI::l10n()->t('j F, Y');
+                       $short_bd_format = DI::l10n()->t('j F');
+
+                       $dob = DI::l10n()->getDay(
+                               intval($a->profile['dob']) ?
+                                       DateTimeFormat::utc($a->profile['dob'] . ' 00:00 +00:00', $year_bd_format)
+                                       : DateTimeFormat::utc('2001-' . substr($a->profile['dob'], 5) . ' 00:00 +00:00', $short_bd_format)
+                       );
+
+                       $basic_fields += self::buildField('dob', DI::l10n()->t('Birthday:'), $dob);
+
+                       if ($age = Temporal::getAgeByTimezone($a->profile['dob'], $a->profile['timezone'])) {
+                               $basic_fields += self::buildField('age', DI::l10n()->t('Age: '), DI::l10n()->tt('%d year old', '%d years old', $age));
+                       }
+               }
+
+               if ($a->profile['pdesc']) {
+                       $basic_fields += self::buildField('pdesc', DI::l10n()->t('Description:'), HTML::toLink($a->profile['pdesc']));
+               }
+
+               if ($a->profile['xmpp']) {
+                       $basic_fields += self::buildField('xmpp', DI::l10n()->t('XMPP:'), $a->profile['xmpp']);
+               }
+
+               if ($a->profile['homepage']) {
+                       $basic_fields += self::buildField('homepage', DI::l10n()->t('Homepage:'), HTML::toLink($a->profile['homepage']));
+               }
+
+               if (
+                       $a->profile['address']
+                       || $a->profile['locality']
+                       || $a->profile['postal-code']
+                       || $a->profile['region']
+                       || $a->profile['country-name']
+               ) {
+                       $basic_fields += self::buildField('location', DI::l10n()->t('Location:'), ProfileModel::formatLocation($a->profile));
+               }
+
+               if ($a->profile['pub_keywords']) {
+                       $tags = [];
+                       foreach (explode(',', $a->profile['pub_keywords']) as $tag_label) {
+                               $tags[] = [
+                                       'url' => '/search?tag=' . $tag_label,
+                                       'label' => Term::TAG_CHARACTER[Term::HASHTAG] . $tag_label,
+                               ];
+                       }
+
+                       $basic_fields += self::buildField('pub_keywords', DI::l10n()->t('Tags:'), $tags);
+               }
+
+               $custom_fields = [];
+
+               // Defaults to the current logged in user self contact id to show self-only fields
+               $contact_id = $view_as_contact_id ?: $remote_contact_id ?: 0;
+
+               if ($is_owner && $contact_id === 0) {
+                       $profile_fields = DI::profileField()->selectByUserId($a->profile_uid);
+               } else {
+                       $profile_fields = DI::profileField()->selectByContactId($contact_id, $a->profile_uid);
+               }
+
+               foreach ($profile_fields as $profile_field) {
+                       $custom_fields += self::buildField(
+                               'custom_' . $profile_field->order,
+                               $profile_field->label,
+                               BBCode::convert($profile_field->value),
+                               'aprofile custom'
+                       );
+               };
+
+               //show subcribed forum if it is enabled in the usersettings
+               if (Feature::isEnabled($a->profile_uid, 'forumlist_profile')) {
+                       $custom_fields += self::buildField(
+                               'forumlist',
+                               DI::l10n()->t('Forums:'),
+                               ForumManager::profileAdvanced($a->profile_uid)
+                       );
+               }
+
+               $tpl = Renderer::getMarkupTemplate('profile/index.tpl');
+               $o .= Renderer::replaceMacros($tpl, [
+                       '$title' => DI::l10n()->t('Profile'),
+                       '$view_as_contacts' => $view_as_contacts,
+                       '$view_as_contact_id' => $view_as_contact_id,
+                       '$view_as' => DI::l10n()->t('View profile as:'),
+                       '$basic' => DI::l10n()->t('Basic'),
+                       '$advanced' => DI::l10n()->t('Advanced'),
+                       '$is_owner' => $a->profile_uid == local_user(),
+                       '$query_string' => DI::args()->getQueryString(),
+                       '$basic_fields' => $basic_fields,
+                       '$custom_fields' => $custom_fields,
+                       '$profile' => $a->profile,
+                       '$edit_link' => [
+                               'url' => DI::baseUrl() . '/settings/profile', DI::l10n()->t('Edit profile'),
+                               'title' => '',
+                               'label' => DI::l10n()->t('Edit profile')
+                       ],
+               ]);
+
+               Hook::callAll('profile_advanced', $o);
+
+               return $o;
+       }
+
+       /**
+        * Creates a profile field structure to be used in the profile template
+        *
+        * @param string $name  Arbitrary name of the field
+        * @param string $label Display label of the field
+        * @param mixed  $value Display value of the field
+        * @param string $class Optional CSS class to apply to the field
+        * @return array
+        */
+       private static function buildField(string $name, string $label, $value, string $class = 'aprofile')
+       {
+               return [$name => [
+                       'id' => 'aprofile-' . $name,
+                       'class' => $class,
+                       'label' => $label,
+                       'value' => $value,
+               ]];
+       }
+
+       private static function buildHtmlHead(array $profile, string $nickname, int $remote_contact_id)
+       {
+               $baseUrl = DI::baseUrl();
+
+               $htmlhead = "\n";
+
+               if (!empty($profile['page-flags']) && $profile['page-flags'] == User::PAGE_FLAGS_COMMUNITY) {
+                       $htmlhead .= '<meta name="friendica.community" content="true" />' . "\n";
+               }
+
+               if (!empty($profile['openidserver'])) {
+                       $htmlhead .= '<link rel="openid.server" href="' . $profile['openidserver'] . '" />' . "\n";
+               }
+
+               if (!empty($profile['openid'])) {
+                       $delegate = strstr($profile['openid'], '://') ? $profile['openid'] : 'https://' . $profile['openid'];
+                       $htmlhead .= '<link rel="openid.delegate" href="' . $delegate . '" />' . "\n";
+               }
+
+               // site block
+               $blocked   = !local_user() && !$remote_contact_id && DI::config()->get('system', 'block_public');
+               $userblock = !local_user() && !$remote_contact_id && $profile['hidewall'];
+               if (!$blocked && !$userblock) {
+                       $keywords = str_replace(['#', ',', ' ', ',,'], ['', ' ', ',', ','], $profile['pub_keywords'] ?? '');
+                       if (strlen($keywords)) {
+                               $htmlhead .= '<meta name="keywords" content="' . $keywords . '" />' . "\n";
+                       }
+               }
+
+               $htmlhead .= '<meta name="dfrn-global-visibility" content="' . ($profile['net-publish'] ? 'true' : 'false') . '" />' . "\n";
+
+               if (!$profile['net-publish'] || $profile['hidewall']) {
+                       $htmlhead .= '<meta content="noindex, noarchive" name="robots" />' . "\n";
+               }
+
+               $htmlhead .= '<link rel="alternate" type="application/atom+xml" href="' . $baseUrl . '/dfrn_poll/' . $nickname . '" title="DFRN: ' . DI::l10n()->t('%s\'s timeline', $profile['username']) . '"/>' . "\n";
+               $htmlhead .= '<link rel="alternate" type="application/atom+xml" href="' . $baseUrl . '/feed/' . $nickname . '/" title="' . DI::l10n()->t('%s\'s posts', $profile['username']) . '"/>' . "\n";
+               $htmlhead .= '<link rel="alternate" type="application/atom+xml" href="' . $baseUrl . '/feed/' . $nickname . '/comments" title="' . DI::l10n()->t('%s\'s comments', $profile['username']) . '"/>' . "\n";
+               $htmlhead .= '<link rel="alternate" type="application/atom+xml" href="' . $baseUrl . '/feed/' . $nickname . '/activity" title="' . DI::l10n()->t('%s\'s timeline', $profile['username']) . '"/>' . "\n";
+               $uri = urlencode('acct:' . $profile['nickname'] . '@' . $baseUrl->getHostname() . ($baseUrl->getUrlPath() ? '/' . $baseUrl->getUrlPath() : ''));
+               $htmlhead .= '<link rel="lrdd" type="application/xrd+xml" href="' . $baseUrl . '/xrd/?uri=' . $uri . '" />' . "\n";
+               header('Link: <' . $baseUrl . '/xrd/?uri=' . $uri . '>; rel="lrdd"; type="application/xrd+xml"', false);
+
+               $dfrn_pages = ['request', 'confirm', 'notify', 'poll'];
+               foreach ($dfrn_pages as $dfrn) {
+                       $htmlhead .= '<link rel="dfrn-' . $dfrn . '" href="' . $baseUrl . '/dfrn_' . $dfrn . '/' . $nickname . '" />' . "\n";
+               }
+               $htmlhead .= '<link rel="dfrn-poco" href="' . $baseUrl . '/poco/' . $nickname . '" />' . "\n";
+
+               return $htmlhead;
+       }
+}
diff --git a/src/Module/Profile/Status.php b/src/Module/Profile/Status.php
new file mode 100644 (file)
index 0000000..ce68a8f
--- /dev/null
@@ -0,0 +1,221 @@
+<?php
+
+namespace Friendica\Module\Profile;
+
+use Friendica\Content\Nav;
+use Friendica\Content\Pager;
+use Friendica\Content\Widget;
+use Friendica\Core\ACL;
+use Friendica\Core\Session;
+use Friendica\Database\DBA;
+use Friendica\DI;
+use Friendica\Model\Item;
+use Friendica\Model\Profile as ProfileModel;
+use Friendica\Model\User;
+use Friendica\Module\BaseProfile;
+use Friendica\Module\Security\Login;
+use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Security;
+use Friendica\Util\Strings;
+use Friendica\Util\XML;
+
+class Status extends BaseProfile
+{
+       public static function content(array $parameters = [])
+       {
+               $args = DI::args();
+
+               $a = DI::app();
+
+               ProfileModel::load($a, $parameters['nickname']);
+
+               if (!$a->profile['net-publish'] || $a->profile['hidewall']) {
+                       DI::page()['htmlhead'] .= '<meta content="noindex, noarchive" name="robots" />' . "\n";
+               }
+
+               DI::page()['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . DI::baseUrl() . '/dfrn_poll/' . $parameters['nickname'] . '" title="DFRN: ' . DI::l10n()->t('%s\'s timeline', $a->profile['username']) . '"/>' . "\n";
+               DI::page()['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . DI::baseUrl() . '/feed/' . $parameters['nickname'] . '/" title="' . DI::l10n()->t('%s\'s posts', $a->profile['username']) . '"/>' . "\n";
+               DI::page()['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . DI::baseUrl() . '/feed/' . $parameters['nickname'] . '/comments" title="' . DI::l10n()->t('%s\'s comments', $a->profile['username']) . '"/>' . "\n";
+               DI::page()['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . DI::baseUrl() . '/feed/' . $parameters['nickname'] . '/activity" title="' . DI::l10n()->t('%s\'s timeline', $a->profile['username']) . '"/>' . "\n";
+
+               $category = $datequery = $datequery2 = '';
+
+               $dtFormat = DI::dtFormat();
+
+               if ($args->getArgc() > 3) {
+                       for ($x = 3; $x < $args->getArgc(); $x++) {
+                               if ($dtFormat->isYearMonth($args->get($x))) {
+                                       if ($datequery) {
+                                               $datequery2 = Strings::escapeHtml($args->get($x));
+                                       } else {
+                                               $datequery = Strings::escapeHtml($args->get($x));
+                                       }
+                               } else {
+                                       $category = $args->get($x);
+                               }
+                       }
+               }
+
+               if (empty($category)) {
+                       $category = $_GET['category'] ?? '';
+               }
+
+               $hashtags = $_GET['tag'] ?? '';
+
+               if (DI::config()->get('system', 'block_public') && !local_user() && !Session::getRemoteContactID($a->profile['uid'])) {
+                       return Login::form();
+               }
+
+               $o = '';
+
+               if ($a->profile['uid'] == local_user()) {
+                       Nav::setSelected('home');
+               }
+
+               $remote_contact = Session::getRemoteContactID($a->profile['uid']);
+               $is_owner = local_user() == $a->profile['uid'];
+               $last_updated_key = "profile:" . $a->profile['uid'] . ":" . local_user() . ":" . $remote_contact;
+
+               if (!empty($a->profile['hidewall']) && !$is_owner && !$remote_contact) {
+                       notice(DI::l10n()->t('Access to this profile has been restricted.') . EOL);
+                       return '';
+               }
+
+               $o .= self::getTabsHTML($a, 'status', $is_owner, $a->profile['nickname']);
+
+               $o .= Widget::commonFriendsVisitor($a->profile['uid']);
+
+               $commpage = $a->profile['page-flags'] == User::PAGE_FLAGS_COMMUNITY;
+               $commvisitor = $commpage && $remote_contact;
+
+               DI::page()['aside'] .= Widget::postedByYear(DI::baseUrl() . '/profile/' . $a->profile['nickname'] . '/status', $a->profile['profile_uid'] ?? 0, true);
+               DI::page()['aside'] .= Widget::categories(DI::baseUrl() . '/profile/' . $a->profile['nickname'] . '/status', XML::escape($category));
+               DI::page()['aside'] .= Widget::tagCloud();
+
+               if (Security::canWriteToUserWall($a->profile['uid'])) {
+                       $x = [
+                               'is_owner' => $is_owner,
+                               'allow_location' => ($is_owner || $commvisitor) && $a->profile['allow_location'],
+                               'default_location' => $is_owner ? $a->user['default-location'] : '',
+                               'nickname' => $a->profile['nickname'],
+                               'lockstate' => is_array($a->user)
+                               && (strlen($a->user['allow_cid'])
+                                       || strlen($a->user['allow_gid'])
+                                       || strlen($a->user['deny_cid'])
+                                       || strlen($a->user['deny_gid'])
+                               ) ? 'lock' : 'unlock',
+                               'acl' => $is_owner ? ACL::getFullSelectorHTML(DI::page(), $a->user, true) : '',
+                               'bang' => '',
+                               'visitor' => $is_owner || $commvisitor ? 'block' : 'none',
+                               'profile_uid' => $a->profile['uid'],
+                       ];
+
+                       $o .= status_editor($a, $x);
+               }
+
+               // Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
+               $sql_extra = Item::getPermissionsSQLByUserId($a->profile['uid']);
+               $sql_extra2 = '';
+
+               $last_updated_array = Session::get('last_updated', []);
+
+               $sql_post_table = "";
+
+               if (!empty($category)) {
+                       $sql_post_table = sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ",
+                               DBA::escape(Strings::protectSprintf($category)), intval(TERM_OBJ_POST), intval(TERM_CATEGORY), intval($a->profile['uid']));
+               }
+
+               if (!empty($hashtags)) {
+                       $sql_post_table .= sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ",
+                               DBA::escape(Strings::protectSprintf($hashtags)), intval(TERM_OBJ_POST), intval(TERM_HASHTAG), intval($a->profile['uid']));
+               }
+
+               if (!empty($datequery)) {
+                       $sql_extra2 .= Strings::protectSprintf(sprintf(" AND `thread`.`received` <= '%s' ", DBA::escape(DateTimeFormat::convert($datequery, 'UTC', date_default_timezone_get()))));
+               }
+               if (!empty($datequery2)) {
+                       $sql_extra2 .= Strings::protectSprintf(sprintf(" AND `thread`.`received` >= '%s' ", DBA::escape(DateTimeFormat::convert($datequery2, 'UTC', date_default_timezone_get()))));
+               }
+
+               // Does the profile page belong to a forum?
+               // If not then we can improve the performance with an additional condition
+               $condition = ['uid' => $a->profile['uid'], 'page-flags' => [User::PAGE_FLAGS_COMMUNITY, User::PAGE_FLAGS_PRVGROUP]];
+               if (!DBA::exists('user', $condition)) {
+                       $sql_extra3 = sprintf(" AND `thread`.`contact-id` = %d ", intval(intval($a->profile['contact_id'])));
+               } else {
+                       $sql_extra3 = "";
+               }
+
+               //  check if we serve a mobile device and get the user settings
+               //  accordingly
+               if (DI::mode()->isMobile()) {
+                       $itemspage_network = DI::pConfig()->get(local_user(), 'system', 'itemspage_mobile_network', 10);
+               } else {
+                       $itemspage_network = DI::pConfig()->get(local_user(), 'system', 'itemspage_network', 20);
+               }
+
+               //  now that we have the user settings, see if the theme forces
+               //  a maximum item number which is lower then the user choice
+               if (($a->force_max_items > 0) && ($a->force_max_items < $itemspage_network)) {
+                       $itemspage_network = $a->force_max_items;
+               }
+
+               $pager = new Pager($args->getQueryString(), $itemspage_network);
+
+               $pager_sql = sprintf(" LIMIT %d, %d ", $pager->getStart(), $pager->getItemsPerPage());
+
+               $items_stmt = DBA::p(
+                       "SELECT `item`.`uri`
+                       FROM `thread`
+                       STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
+                       $sql_post_table
+                       STRAIGHT_JOIN `contact`
+                       ON `contact`.`id` = `thread`.`contact-id`
+                               AND NOT `contact`.`blocked`
+                               AND NOT `contact`.`pending`
+                       WHERE `thread`.`uid` = ?
+                               AND `thread`.`visible`
+                               AND NOT `thread`.`deleted`
+                               AND NOT `thread`.`moderated`
+                               AND `thread`.`wall`
+                               $sql_extra3
+                               $sql_extra
+                               $sql_extra2
+                       ORDER BY `thread`.`received` DESC
+                       $pager_sql",
+                       $a->profile['uid']
+               );
+
+               // Set a time stamp for this page. We will make use of it when we
+               // search for new items (update routine)
+               $last_updated_array[$last_updated_key] = time();
+               Session::set('last_updated', $last_updated_array);
+
+               if ($is_owner && !DI::config()->get('theme', 'hide_eventlist')) {
+                       $o .= ProfileModel::getBirthdays();
+                       $o .= ProfileModel::getEventsReminderHTML();
+               }
+
+               if ($is_owner) {
+                       $unseen = Item::exists(['wall' => true, 'unseen' => true, 'uid' => local_user()]);
+                       if ($unseen) {
+                               Item::update(['unseen' => false], ['wall' => true, 'unseen' => true, 'uid' => local_user()]);
+                       }
+               }
+
+               $items = DBA::toArray($items_stmt);
+
+               if ($pager->getStart() == 0 && !empty($a->profile['uid'])) {
+                       $pinned_items = Item::selectPinned($a->profile['uid'], ['uri', 'pinned']);
+                       $pinned = Item::inArray($pinned_items);
+                       $items = array_merge($items, $pinned);
+               }
+
+               $o .= conversation($a, $items, $pager, 'profile', false, false, 'pinned_received', $a->profile['uid']);
+
+               $o .= $pager->renderMinimal(count($items));
+
+               return $o;
+       }
+}
diff --git a/src/Module/Settings/Profile/Index.php b/src/Module/Settings/Profile/Index.php
new file mode 100644 (file)
index 0000000..b0eb194
--- /dev/null
@@ -0,0 +1,306 @@
+<?php
+
+namespace Friendica\Module\Settings\Profile;
+
+use Friendica\Core\ACL;
+use Friendica\Core\Hook;
+use Friendica\Core\Protocol;
+use Friendica\Core\Renderer;
+use Friendica\Core\Session;
+use Friendica\Core\Theme;
+use Friendica\Core\Worker;
+use Friendica\Database\DBA;
+use Friendica\DI;
+use Friendica\Model\Contact;
+use Friendica\Model\GContact;
+use Friendica\Model\Profile;
+use Friendica\Model\ProfileField;
+use Friendica\Model\User;
+use Friendica\Module\BaseSettingsModule;
+use Friendica\Module\Security\Login;
+use Friendica\Network\HTTPException;
+use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Strings;
+use Friendica\Util\Temporal;
+
+class Index extends BaseSettingsModule
+{
+       public static function post(array $parameters = [])
+       {
+               if (!local_user()) {
+                       return;
+               }
+
+               $profile = Profile::getByUID(local_user());
+               if (!DBA::isResult($profile)) {
+                       return;
+               }
+
+               self::checkFormSecurityTokenRedirectOnError('/settings/profile', 'settings_profile');
+
+               Hook::callAll('profile_post', $_POST);
+
+               $dob = Strings::escapeHtml(trim($_POST['dob'] ?? '0000-00-00'));
+
+               $y = substr($dob, 0, 4);
+               if ((!ctype_digit($y)) || ($y < 1900)) {
+                       $ignore_year = true;
+               } else {
+                       $ignore_year = false;
+               }
+
+               if (!in_array($dob, ['0000-00-00', DBA::NULL_DATE])) {
+                       if (strpos($dob, '0000-') === 0 || strpos($dob, '0001-') === 0) {
+                               $ignore_year = true;
+                               $dob = substr($dob, 5);
+                       }
+
+                       if ($ignore_year) {
+                               $dob = '0000-' . DateTimeFormat::utc('1900-' . $dob, 'm-d');
+                       } else {
+                               $dob = DateTimeFormat::utc($dob, 'Y-m-d');
+                       }
+               }
+
+               $name = Strings::escapeTags(trim($_POST['name'] ?? ''));
+               if (!strlen($name)) {
+                       notice(DI::l10n()->t('Profile Name is required.'));
+                       return;
+               }
+
+               $namechanged = $profile['name'] != $name;
+
+               $pdesc = Strings::escapeTags(trim($_POST['pdesc']));
+               $address = Strings::escapeTags(trim($_POST['address']));
+               $locality = Strings::escapeTags(trim($_POST['locality']));
+               $region = Strings::escapeTags(trim($_POST['region']));
+               $postal_code = Strings::escapeTags(trim($_POST['postal_code']));
+               $country_name = Strings::escapeTags(trim($_POST['country_name']));
+               $pub_keywords = self::cleanKeywords(Strings::escapeTags(trim($_POST['pub_keywords'])));
+               $prv_keywords = self::cleanKeywords(Strings::escapeTags(trim($_POST['prv_keywords'])));
+               $xmpp = Strings::escapeTags(trim($_POST['xmpp']));
+               $homepage = Strings::escapeTags(trim($_POST['homepage']));
+               if ((strpos($homepage, 'http') !== 0) && (strlen($homepage))) {
+                       // neither http nor https in URL, add them
+                       $homepage = 'http://' . $homepage;
+               }
+
+               $hide_friends = intval(!empty($_POST['hide-friends']));
+
+               $profileFields = DI::profileField()->selectByUserId(local_user());
+
+               $profileFields = DI::profileField()->updateCollectionFromForm(
+                       local_user(),
+                       $profileFields,
+                       $_REQUEST['profile_field'],
+                       $_REQUEST['profile_field_order']
+               );
+
+               DI::profileField()->saveCollection($profileFields);
+
+               $result = DBA::update(
+                       'profile',
+                       [
+                               'name'         => $name,
+                               'pdesc'        => $pdesc,
+                               'dob'          => $dob,
+                               'address'      => $address,
+                               'locality'     => $locality,
+                               'region'       => $region,
+                               'postal-code'  => $postal_code,
+                               'country-name' => $country_name,
+                               'xmpp'         => $xmpp,
+                               'homepage'     => $homepage,
+                               'pub_keywords' => $pub_keywords,
+                               'prv_keywords' => $prv_keywords,
+                               'hide-friends' => $hide_friends,
+                       ],
+                       ['uid' => local_user()]
+               );
+
+               if ($result) {
+                       info(DI::l10n()->t('Profile updated.'));
+               } else {
+                       notice(DI::l10n()->t('Profile couldn\'t be updated.'));
+                       return;
+               }
+
+               if ($namechanged) {
+                       DBA::update('user', ['username' => $name], ['uid' => local_user()]);
+               }
+
+               Contact::updateSelfFromUserID(local_user());
+
+               // Update global directory in background
+               if (Session::get('my_url') && strlen(DI::config()->get('system', 'directory'))) {
+                       Worker::add(PRIORITY_LOW, 'Directory', Session::get('my_url'));
+               }
+
+               Worker::add(PRIORITY_LOW, 'ProfileUpdate', local_user());
+
+               // Update the global contact for the user
+               GContact::updateForUser(local_user());
+       }
+
+       public static function content(array $parameters = [])
+       {
+               if (!local_user()) {
+                       notice(DI::l10n()->t('You must be logged in to use this module'));
+                       return Login::form();
+               }
+
+               parent::content();
+
+               $o = '';
+
+               $profile = Profile::getByUID(local_user());
+               if (!DBA::isResult($profile)) {
+                       throw new HTTPException\NotFoundException();
+               }
+
+               $a = DI::app();
+
+               DI::page()->registerFooterScript('view/asset/es-jquery-sortable/source/js/jquery-sortable-min.js');
+               DI::page()->registerFooterScript(Theme::getPathForFile('js/module/settings/profile/index.js'));
+
+               $custom_fields = [];
+
+               $profileFields = DI::profileField()->selectByUserId(local_user());
+               foreach ($profileFields as $profileField) {
+                       /** @var ProfileField $profileField */
+                       $defaultPermissions = ACL::getDefaultUserPermissions($profileField->permissionset->toArray());
+
+                       $custom_fields[] = [
+                               'id' => $profileField->id,
+                               'legend' => $profileField->label,
+                               'fields' => [
+                                       'label' => ['profile_field[' . $profileField->id . '][label]', DI::l10n()->t('Label:'), $profileField->label],
+                                       'value' => ['profile_field[' . $profileField->id . '][value]', DI::l10n()->t('Value:'), $profileField->value],
+                                       'acl' => ACL::getFullSelectorHTML(
+                                               DI::page(),
+                                               $a->user,
+                                               false,
+                                               $defaultPermissions,
+                                               ['network' => Protocol::DFRN],
+                                               'profile_field[' . $profileField->id . ']'
+                                       ),
+                               ],
+                               'permissions' => DI::l10n()->t('Field Permissions'),
+                               'permdesc' => DI::l10n()->t("(click to open/close)"),
+                       ];
+               };
+
+               $custom_fields[] = [
+                       'id' => 'new',
+                       'legend' => DI::l10n()->t('Add a new profile field'),
+                       'fields' => [
+                               'label' => ['profile_field[new][label]', DI::l10n()->t('Label:')],
+                               'value' => ['profile_field[new][value]', DI::l10n()->t('Value:')],
+                               'acl' => ACL::getFullSelectorHTML(
+                                       DI::page(),
+                                       $a->user,
+                                       false,
+                                       ['allow_cid' => []],
+                                       ['network' => Protocol::DFRN],
+                                       'profile_field[new]'
+                               ),
+                       ],
+                       'permissions' => DI::l10n()->t('Field Permissions'),
+                       'permdesc' => DI::l10n()->t("(click to open/close)"),
+               ];
+
+               DI::page()['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/profile/index_head.tpl'), [
+                       '$baseurl' => DI::baseUrl()->get(true),
+               ]);
+
+               $opt_tpl = Renderer::getMarkupTemplate('settings/profile/hide-friends.tpl');
+               $hide_friends = Renderer::replaceMacros($opt_tpl, [
+                       '$yesno' => [
+                               'hide-friends', //Name
+                               DI::l10n()->t('Hide contacts and friends:'), //Label
+                               !!$profile['hide-friends'], //Value
+                               '', //Help string
+                               [DI::l10n()->t('No'), DI::l10n()->t('Yes')] //Off - On strings
+                       ],
+                       '$desc' => DI::l10n()->t('Hide your contact/friend list from viewers of this profile?'),
+                       '$yes_str' => DI::l10n()->t('Yes'),
+                       '$no_str' => DI::l10n()->t('No'),
+                       '$yes_selected' => (($profile['hide-friends']) ? ' checked="checked"' : ''),
+                       '$no_selected' => (($profile['hide-friends'] == 0) ? ' checked="checked"' : '')
+               ]);
+
+               $personal_account = !in_array($a->user['page-flags'], [User::PAGE_FLAGS_COMMUNITY, User::PAGE_FLAGS_PRVGROUP]);
+
+               $tpl = Renderer::getMarkupTemplate('settings/profile/index.tpl');
+               $o .= Renderer::replaceMacros($tpl, [
+                       '$personal_account' => $personal_account,
+
+                       '$form_security_token' => self::getFormSecurityToken('settings_profile'),
+                       '$form_security_token_photo' => self::getFormSecurityToken('settings_profile_photo'),
+
+                       '$profile_action' => DI::l10n()->t('Profile Actions'),
+                       '$banner' => DI::l10n()->t('Edit Profile Details'),
+                       '$submit' => DI::l10n()->t('Submit'),
+                       '$profpic' => DI::l10n()->t('Change Profile Photo'),
+                       '$profpiclink' => '/photos/' . $a->user['nickname'],
+                       '$viewprof' => DI::l10n()->t('View this profile'),
+
+                       '$lbl_personal_section' => DI::l10n()->t('Personal'),
+                       '$lbl_picture_section' => DI::l10n()->t('Profile picture'),
+                       '$lbl_location_section' => DI::l10n()->t('Location'),
+                       '$lbl_miscellaneous_section' => DI::l10n()->t('Miscellaneous'),
+                       '$lbl_custom_fields_section' => DI::l10n()->t('Custom Profile Fields'),
+
+                       '$lbl_profile_photo' => DI::l10n()->t('Upload Profile Photo'),
+
+                       '$baseurl' => DI::baseUrl()->get(true),
+                       '$nickname' => $a->user['nickname'],
+                       '$name' => ['name', DI::l10n()->t('Display name:'), $profile['name']],
+                       '$pdesc' => ['pdesc', DI::l10n()->t('Title/Description:'), $profile['pdesc']],
+                       '$dob' => Temporal::getDateofBirthField($profile['dob'], $a->user['timezone']),
+                       '$hide_friends' => $hide_friends,
+                       '$address' => ['address', DI::l10n()->t('Street Address:'), $profile['address']],
+                       '$locality' => ['locality', DI::l10n()->t('Locality/City:'), $profile['locality']],
+                       '$region' => ['region', DI::l10n()->t('Region/State:'), $profile['region']],
+                       '$postal_code' => ['postal_code', DI::l10n()->t('Postal/Zip Code:'), $profile['postal-code']],
+                       '$country_name' => ['country_name', DI::l10n()->t('Country:'), $profile['country-name']],
+                       '$age' => ((intval($profile['dob'])) ? '(' . DI::l10n()->t('Age: ') . DI::l10n()->tt('%d year old', '%d years old', Temporal::getAgeByTimezone($profile['dob'], $a->user['timezone'])) . ')' : ''),
+                       '$xmpp' => ['xmpp', DI::l10n()->t('XMPP (Jabber) address:'), $profile['xmpp'], DI::l10n()->t('The XMPP address will be propagated to your contacts so that they can follow you.')],
+                       '$homepage' => ['homepage', DI::l10n()->t('Homepage URL:'), $profile['homepage']],
+                       '$pub_keywords' => ['pub_keywords', DI::l10n()->t('Public Keywords:'), $profile['pub_keywords'], DI::l10n()->t('(Used for suggesting potential friends, can be seen by others)')],
+                       '$prv_keywords' => ['prv_keywords', DI::l10n()->t('Private Keywords:'), $profile['prv_keywords'], DI::l10n()->t('(Used for searching profiles, never shown to others)')],
+                       '$custom_fields_description' => DI::l10n()->t("<p>Custom fields appear on <a href=\"%s\">your profile page</a>.</p>
+                               <p>You can use BBCodes in the field values.</p>
+                               <p>Reorder by dragging the field title.</p>
+                               <p>Empty the label field to remove a custom field.</p>
+                               <p>Non-public fields can only be seen by the selected Friendica contacts or the Friendica contacts in the selected groups.</p>",
+                               'profile/' . $a->user['nickname']
+                       ),
+                       '$custom_fields' => $custom_fields,
+               ]);
+
+               $arr = ['profile' => $profile, 'entry' => $o];
+               Hook::callAll('profile_edit', $arr);
+
+               return $o;
+       }
+
+       private static function cleanKeywords($keywords)
+       {
+               $keywords = str_replace(',', ' ', $keywords);
+               $keywords = explode(' ', $keywords);
+
+               $cleaned = [];
+               foreach ($keywords as $keyword) {
+                       $keyword = trim(strtolower($keyword));
+                       $keyword = trim($keyword, '#');
+                       if ($keyword != '') {
+                               $cleaned[] = $keyword;
+                       }
+               }
+
+               $keywords = implode(', ', $cleaned);
+
+               return $keywords;
+       }
+}
index 0b3aa85a4b04101bf2e23f7d9f0ed0577866e337..8d04e853602a34da754928e95fb4c43a7bfde77f 100644 (file)
@@ -167,7 +167,11 @@ class UserExport extends BaseSettingsModule
 
 
                $profile = self::exportMultiRow(
-                       sprintf("SELECT * FROM `profile` WHERE `uid` = %d ", intval(local_user()))
+                       sprintf("SELECT *, 'default' AS `profile_name`, 1 AS `is-default` FROM `profile` WHERE `uid` = %d ", intval(local_user()))
+               );
+
+               $profile_fields = self::exportMultiRow(
+                       sprintf("SELECT * FROM `profile_field` WHERE `uid` = %d ", intval(local_user()))
                );
 
                $photo = self::exportMultiRow(
@@ -196,6 +200,7 @@ class UserExport extends BaseSettingsModule
                        'user' => $user,
                        'contact' => $contact,
                        'profile' => $profile,
+                       'profile_fields' => $profile_fields,
                        'photo' => $photo,
                        'pconfig' => $pconfig,
                        'group' => $group,
diff --git a/src/Module/Update/Profile.php b/src/Module/Update/Profile.php
new file mode 100644 (file)
index 0000000..0f959a3
--- /dev/null
@@ -0,0 +1,125 @@
+<?php
+
+namespace Friendica\Module\Update;
+
+use Friendica\BaseModule;
+use Friendica\Content\Pager;
+use Friendica\Core\Session;
+use Friendica\Database\DBA;
+use Friendica\DI;
+use Friendica\Model\Item;
+use Friendica\Model\Profile as ProfileModel;
+use Friendica\Network\HTTPException\ForbiddenException;
+use Friendica\Util\DateTimeFormat;
+
+class Profile extends BaseModule
+{
+       public static function rawContent(array $parameters = [])
+       {
+               $a = DI::app();
+
+               if (DI::config()->get('system', 'block_public') && !local_user() && !Session::getRemoteContactID($a->profile['uid'])) {
+                       throw new ForbiddenException();
+               }
+
+               $o = '';
+
+               $profile_uid = intval($_GET['p'] ?? 0);
+
+               // Ensure we've got a profile owner if updating.
+               $a->profile['uid'] = $profile_uid;
+
+               $remote_contact = Session::getRemoteContactID($a->profile['uid']);
+               $is_owner = local_user() == $a->profile['uid'];
+               $last_updated_key = "profile:" . $a->profile['uid'] . ":" . local_user() . ":" . $remote_contact;
+
+               if (!empty($a->profile['hidewall']) && !$is_owner && !$remote_contact) {
+                       throw new ForbiddenException(DI::l10n()->t('Access to this profile has been restricted.'));
+               }
+
+               // Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
+               $sql_extra = Item::getPermissionsSQLByUserId($a->profile['uid']);
+
+               $last_updated_array = Session::get('last_updated', []);
+
+               $last_updated = $last_updated_array[$last_updated_key] ?? 0;
+
+               // If the page user is the owner of the page we should query for unseen
+               // items. Otherwise use a timestamp of the last succesful update request.
+               if ($is_owner || !$last_updated) {
+                       $sql_extra4 = " AND `item`.`unseen`";
+               } else {
+                       $gmupdate = gmdate(DateTimeFormat::MYSQL, $last_updated);
+                       $sql_extra4 = " AND `item`.`received` > '" . $gmupdate . "'";
+               }
+
+               $items_stmt = DBA::p(
+                       "SELECT DISTINCT(`parent-uri`) AS `uri`, `item`.`created`
+                       FROM `item`
+                       INNER JOIN `contact`
+                       ON `contact`.`id` = `item`.`contact-id`
+                               AND NOT `contact`.`blocked`
+                               AND NOT `contact`.`pending`
+                       WHERE `item`.`uid` = ?
+                               AND `item`.`visible`
+                               AND     (NOT `item`.`deleted` OR `item`.`gravity` = ?)
+                               AND NOT `item`.`moderated`
+                               AND `item`.`wall`
+                               $sql_extra4
+                               $sql_extra
+                       ORDER BY `item`.`received` DESC",
+                       $a->profile['uid'],
+                       GRAVITY_ACTIVITY
+               );
+
+               if (!DBA::isResult($items_stmt)) {
+                       return '';
+               }
+
+               $pager = new Pager(DI::args()->getQueryString());
+
+               // Set a time stamp for this page. We will make use of it when we
+               // search for new items (update routine)
+               $last_updated_array[$last_updated_key] = time();
+               Session::set('last_updated', $last_updated_array);
+
+               if ($is_owner && !$profile_uid && !DI::config()->get('theme', 'hide_eventlist')) {
+                       $o .= ProfileModel::getBirthdays();
+                       $o .= ProfileModel::getEventsReminderHTML();
+               }
+
+               if ($is_owner) {
+                       $unseen = Item::exists(['wall' => true, 'unseen' => true, 'uid' => local_user()]);
+                       if ($unseen) {
+                               Item::update(['unseen' => false], ['wall' => true, 'unseen' => true, 'uid' => local_user()]);
+                       }
+               }
+
+               $items = DBA::toArray($items_stmt);
+
+               $o .= conversation($a, $items, $pager, 'profile', $profile_uid, false, 'received', $a->profile['uid']);
+
+               header("Content-type: text/html");
+               echo "<!DOCTYPE html><html><body>\r\n";
+               // We can remove this hack once Internet Explorer recognises HTML5 natively
+               echo "<section>";
+               echo $o;
+               if (DI::pConfig()->get(local_user(), "system", "bandwidth_saver")) {
+                       $replace = "<br />".DI::l10n()->t("[Embedded content - reload page to view]")."<br />";
+                       $pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
+                       $o = preg_replace($pattern, $replace, $o);
+                       $pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
+                       $o = preg_replace($pattern, $replace, $o);
+                       $pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
+                       $o = preg_replace($pattern, $replace, $o);
+                       $pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
+                       $o = preg_replace($pattern, $replace, $o);
+               }
+
+               // reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well
+               echo str_replace("\t", "       ", $o);
+               echo "</section>";
+               echo "</body></html>\r\n";
+               exit();
+       }
+}
diff --git a/src/Object/EMail/IEmail.php b/src/Object/EMail/IEmail.php
new file mode 100644 (file)
index 0000000..6a159c0
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+
+namespace Friendica\Object\EMail;
+
+use Friendica\Util\Emailer;
+
+/**
+ * Interface for a single mail, which can be send through Emailer::send()
+ *
+ * @see Emailer::send()
+ */
+interface IEmail
+{
+       /**
+        * Gets the senders name for this email
+        *
+        * @return string
+        */
+       function getFromName();
+
+       /**
+        * Gets the senders email address for this email
+        *
+        * @return string
+        */
+       function getFromAddress();
+
+       /**
+        * Gets the UID of the sender of this email
+        *
+        * @return int|null
+        */
+       function getRecipientUid();
+
+       /**
+        * Gets the reply-to address for this email
+        *
+        * @return string
+        */
+       function getReplyTo();
+
+       /**
+        * Gets the senders email address
+        *
+        * @return string
+        */
+       function getToAddress();
+
+       /**
+        * Gets the subject of this email
+        *
+        * @return string
+        */
+       function getSubject();
+
+       /**
+        * Gets the message body of this email (either html or plaintext)
+        *
+        * @param boolean $plain True, if returned as plaintext
+        *
+        * @return string
+        */
+       function getMessage(bool $plain = false);
+
+       /**
+        * Gets any additional mail header
+        *
+        * @return string
+        */
+       function getAdditionalMailHeader();
+}
diff --git a/src/Object/EMail/ItemCCEMail.php b/src/Object/EMail/ItemCCEMail.php
new file mode 100644 (file)
index 0000000..1f1398f
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+namespace Friendica\Object\EMail;
+
+use Friendica\App;
+use Friendica\App\BaseURL;
+use Friendica\Content\Text\HTML;
+use Friendica\Core\L10n;
+use Friendica\Model\Item;
+use Friendica\Object\Email;
+
+/**
+ * Class for creating CC emails based on a received item
+ */
+class ItemCCEMail extends Email
+{
+       public function __construct(App $a, L10n $l10n, BaseURL $baseUrl, array $item, string $toAddress, string $authorThumb)
+       {
+               $disclaimer = '<hr />' . $l10n->t('This message was sent to you by %s, a member of the Friendica social network.', $a->user['username'])
+                             . '<br />';
+               $disclaimer .= $l10n->t('You may visit them online at %s', $baseUrl . '/profile/' . $a->user['nickname']) . EOL;
+               $disclaimer .= $l10n->t('Please contact the sender by replying to this post if you do not wish to receive these messages.') . EOL;
+               if (!$item['title'] == '') {
+                       $subject = Email::encodeHeader($item['title'], 'UTF-8');
+               } else {
+                       $subject = Email::encodeHeader('[Friendica]' . ' ' . $l10n->t('%s posted an update.', $a->user['username']), 'UTF-8');
+               }
+               $link    = '<a href="' . $baseUrl . '/profile/' . $a->user['nickname'] . '"><img src="' . $authorThumb . '" alt="' . $a->user['username'] . '" /></a><br /><br />';
+               $html    = Item::prepareBody($item);
+               $message = '<html><body>' . $link . $html . $disclaimer . '</body></html>';;
+
+               parent::__construct($a->user['username'], $a->user['email'], $a->user['email'], $toAddress,
+                       $subject, $message, HTML::toPlaintext($html . $disclaimer));
+       }
+}
diff --git a/src/Object/Email.php b/src/Object/Email.php
new file mode 100644 (file)
index 0000000..23e1fcf
--- /dev/null
@@ -0,0 +1,135 @@
+<?php
+
+namespace Friendica\Object;
+
+use Friendica\Object\EMail\IEmail;
+
+/**
+ * The default implementation of the IEmail interface
+ *
+ * Provides the possibility to reuse the email instance with new recipients (@see Email::withRecipient())
+ */
+class Email implements IEmail
+{
+       /** @var string */
+       private $fromName;
+       /** @var string */
+       private $fromAddress;
+       /** @var string */
+       private $replyTo;
+
+       /** @var string */
+       private $toAddress;
+
+       /** @var string */
+       private $subject;
+       /** @var string */
+       private $msgHtml;
+       /** @var string */
+       private $msgText;
+
+       /** @var string */
+       private $additionalMailHeader = '';
+       /** @var int|null */
+       private $toUid = null;
+
+       public function __construct(string $fromName, string $fromAddress, string $replyTo, string $toAddress,
+                                   string $subject, string $msgHtml, string $msgText,
+                                   string $additionalMailHeader = '', int $toUid = null)
+       {
+               $this->fromName             = $fromName;
+               $this->fromAddress          = $fromAddress;
+               $this->replyTo              = $replyTo;
+               $this->toAddress            = $toAddress;
+               $this->subject              = $subject;
+               $this->msgHtml              = $msgHtml;
+               $this->msgText              = $msgText;
+               $this->additionalMailHeader = $additionalMailHeader;
+               $this->toUid                = $toUid;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getFromName()
+       {
+               return $this->fromName;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getFromAddress()
+       {
+               return $this->fromAddress;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getReplyTo()
+       {
+               return $this->replyTo;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getToAddress()
+       {
+               return $this->toAddress;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getSubject()
+       {
+               return $this->subject;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getMessage(bool $plain = false)
+       {
+               if ($plain) {
+                       return $this->msgText;
+               } else {
+                       return $this->msgHtml;
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getAdditionalMailHeader()
+       {
+               return $this->additionalMailHeader;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getRecipientUid()
+       {
+               return $this->toUid;
+       }
+
+       /**
+        * Returns the current email with a new recipient
+        *
+        * @param string $email The email of the recipient
+        * @param int    $uid   The (optional) UID of the recipient for further infos
+        *
+        * @return static
+        */
+       public function withRecipient(string $email, int $uid = null)
+       {
+               $newEmail            = clone $this;
+               $newEmail->toAddress = $email;
+               $newEmail->toUid     = $uid;
+
+               return $newEmail;
+       }
+}
diff --git a/src/Object/Notification/Introduction.php b/src/Object/Notification/Introduction.php
new file mode 100644 (file)
index 0000000..19fda4c
--- /dev/null
@@ -0,0 +1,305 @@
+<?php
+
+namespace Friendica\Object\Notification;
+
+/**
+ * A view-only object for printing introduction notifications to the frontend
+ */
+class Introduction implements \JsonSerializable
+{
+       /** @var string */
+       private $label = '';
+       /** @var string */
+       private $type = '';
+       /** @var integer */
+       private $intro_id = -1;
+       /** @var string */
+       private $madeBy = '';
+       /** @var string */
+       private $madeByUrl = '';
+       /** @var string */
+       private $madeByZrl = '';
+       /** @var string */
+       private $madeByAddr = '';
+       /** @var integer */
+       private $contactId = -1;
+       /** @var string */
+       private $photo = '';
+       /** @var string */
+       private $name = '';
+       /** @var string */
+       private $url = '';
+       /** @var string */
+       private $zrl = '';
+       /** @var boolean */
+       private $hidden = false;
+       /** @var integer */
+       private $postNewFriend = -1;
+       /** @var boolean */
+       private $knowYou = false;
+       /** @var string */
+       private $note = '';
+       /** @var string */
+       private $request = '';
+       /** @var int */
+       private $dfrnId = -1;
+       /** @var string */
+       private $addr = '';
+       /** @var string */
+       private $network = '';
+       /** @var int */
+       private $uid = -1;
+       /** @var string */
+       private $keywords = '';
+       /** @var string */
+       private $gender = '';
+       /** @var string */
+       private $location = '';
+       /** @var string */
+       private $about = '';
+
+       /**
+        * @return string
+        */
+       public function getLabel()
+       {
+               return $this->label;
+       }
+
+       /**
+        * @return string
+        */
+       public function getType()
+       {
+               return $this->type;
+       }
+
+       /**
+        * @return int
+        */
+       public function getIntroId()
+       {
+               return $this->intro_id;
+       }
+
+       /**
+        * @return string
+        */
+       public function getMadeBy()
+       {
+               return $this->madeBy;
+       }
+
+       /**
+        * @return string
+        */
+       public function getMadeByUrl()
+       {
+               return $this->madeByUrl;
+       }
+
+       /**
+        * @return string
+        */
+       public function getMadeByZrl()
+       {
+               return $this->madeByZrl;
+       }
+
+       /**
+        * @return string
+        */
+       public function getMadeByAddr()
+       {
+               return $this->madeByAddr;
+       }
+
+       /**
+        * @return int
+        */
+       public function getContactId()
+       {
+               return $this->contactId;
+       }
+
+       /**
+        * @return string
+        */
+       public function getPhoto()
+       {
+               return $this->photo;
+       }
+
+       /**
+        * @return string
+        */
+       public function getName()
+       {
+               return $this->name;
+       }
+
+       /**
+        * @return string
+        */
+       public function getUrl()
+       {
+               return $this->url;
+       }
+
+       /**
+        * @return string
+        */
+       public function getZrl()
+       {
+               return $this->zrl;
+       }
+
+       /**
+        * @return bool
+        */
+       public function isHidden()
+       {
+               return $this->hidden;
+       }
+
+       /**
+        * @return int
+        */
+       public function getPostNewFriend()
+       {
+               return $this->postNewFriend;
+       }
+
+       /**
+        * @return string
+        */
+       public function getKnowYou()
+       {
+               return $this->knowYou;
+       }
+
+       /**
+        * @return string
+        */
+       public function getNote()
+       {
+               return $this->note;
+       }
+
+       /**
+        * @return string
+        */
+       public function getRequest()
+       {
+               return $this->request;
+       }
+
+       /**
+        * @return string
+        */
+       public function getDfrnId()
+       {
+               return $this->dfrnId;
+       }
+
+       /**
+        * @return string
+        */
+       public function getAddr()
+       {
+               return $this->addr;
+       }
+
+       /**
+        * @return string
+        */
+       public function getNetwork()
+       {
+               return $this->network;
+       }
+
+       /**
+        * @return int
+        */
+       public function getUid()
+       {
+               return $this->uid;
+       }
+
+       /**
+        * @return string
+        */
+       public function getKeywords()
+       {
+               return $this->keywords;
+       }
+
+       /**
+        * @return string
+        */
+       public function getGender()
+       {
+               return $this->gender;
+       }
+
+       /**
+        * @return string
+        */
+       public function getLocation()
+       {
+               return $this->location;
+       }
+
+       /**
+        * @return string
+        */
+       public function getAbout()
+       {
+               return $this->about;
+       }
+
+       public function __construct(array $data = [])
+       {
+               $this->label         = $data['label'] ?? '';
+               $this->type          = $data['str_type'] ?? '';
+               $this->intro_id      = $data['$intro_id'] ?? -1;
+               $this->madeBy        = $data['madeBy'] ?? '';
+               $this->madeByUrl     = $data['madeByUrl'] ?? '';
+               $this->madeByZrl     = $data['madeByZrl'] ?? '';
+               $this->madeByAddr    = $data['madeByAddr'] ?? '';
+               $this->contactId     = $data['contactId'] ?? '';
+               $this->photo         = $data['photo'] ?? '';
+               $this->name          = $data['name'] ?? '';
+               $this->url           = $data['url'] ?? '';
+               $this->zrl           = $data['zrl'] ?? '';
+               $this->hidden        = $data['hidden'] ?? false;
+               $this->postNewFriend = $data['postNewFriend'] ?? '';
+               $this->knowYou       = $data['knowYou'] ?? false;
+               $this->note          = $data['note'] ?? '';
+               $this->request       = $data['request'] ?? '';
+               $this->dfrnId        = $data['dfrn_id'] ?? -1;
+               $this->addr          = $data['addr'] ?? '';
+               $this->network       = $data['network'] ?? '';
+               $this->uid           = $data['uid'] ?? -1;
+               $this->keywords      = $data['keywords'] ?? '';
+               $this->gender        = $data['gender'] ?? '';
+               $this->location      = $data['location'] ?? '';
+               $this->about         = $data['about'] ?? '';
+       }
+
+       /**
+        * @inheritDoc
+        */
+       public function jsonSerialize()
+       {
+               return $this->toArray();
+       }
+
+       /**
+        * @return array
+        */
+       public function toArray()
+       {
+               return get_object_vars($this);
+       }
+}
diff --git a/src/Object/Notification/Notification.php b/src/Object/Notification/Notification.php
new file mode 100644 (file)
index 0000000..bb29fd0
--- /dev/null
@@ -0,0 +1,124 @@
+<?php
+
+namespace Friendica\Object\Notification;
+
+/**
+ * A view-only object for printing item notifications to the frontend
+ */
+class Notification implements \JsonSerializable
+{
+       const SYSTEM   = 'system';
+       const PERSONAL = 'personal';
+       const NETWORK  = 'network';
+       const INTRO    = 'intro';
+       const HOME     = 'home';
+
+       /** @var string */
+       private $label = '';
+       /** @var string */
+       private $link = '';
+       /** @var string */
+       private $image = '';
+       /** @var string */
+       private $url = '';
+       /** @var string */
+       private $text = '';
+       /** @var string */
+       private $when = '';
+       /** @var string */
+       private $ago = '';
+       /** @var boolean */
+       private $seen = false;
+
+       /**
+        * @return string
+        */
+       public function getLabel()
+       {
+               return $this->label;
+       }
+
+       /**
+        * @return string
+        */
+       public function getLink()
+       {
+               return $this->link;
+       }
+
+       /**
+        * @return string
+        */
+       public function getImage()
+       {
+               return $this->image;
+       }
+
+       /**
+        * @return string
+        */
+       public function getUrl()
+       {
+               return $this->url;
+       }
+
+       /**
+        * @return string
+        */
+       public function getText()
+       {
+               return $this->text;
+       }
+
+       /**
+        * @return string
+        */
+       public function getWhen()
+       {
+               return $this->when;
+       }
+
+       /**
+        * @return string
+        */
+       public function getAgo()
+       {
+               return $this->ago;
+       }
+
+       /**
+        * @return bool
+        */
+       public function isSeen()
+       {
+               return $this->seen;
+       }
+
+       public function __construct(array $data)
+       {
+               $this->label = $data['label'] ?? '';
+               $this->link  = $data['link'] ?? '';
+               $this->image = $data['image'] ?? '';
+               $this->url   = $data['url'] ?? '';
+               $this->text  = $data['text'] ?? '';
+               $this->when  = $data['when'] ?? '';
+               $this->ago   = $data['ago'] ?? '';
+               $this->seen  = $data['seen'] ?? false;
+       }
+
+       /**
+        * @inheritDoc
+        */
+       public function jsonSerialize()
+       {
+               return get_object_vars($this);
+       }
+
+       /**
+        * @return array
+        */
+       public function toArray()
+       {
+               return get_object_vars($this);
+       }
+}
index c9d39dede7952cf7c02d08cbbadbbf382385c805..23301456a98b178291927b1174f5a066b88822fc 100644 (file)
@@ -224,7 +224,7 @@ class Transmitter
                }
 
                $fields = ['locality', 'region', 'country-name'];
-               $profile = DBA::selectFirst('profile', $fields, ['uid' => $uid, 'is-default' => true]);
+               $profile = DBA::selectFirst('profile', $fields, ['uid' => $uid]);
                if (!DBA::isResult($profile)) {
                        return [];
                }
index f649df558f2690149ddb39a67c5499291d3250ce..424b519063da5385fb0ac06ab6314cbab5ddd134 100644 (file)
@@ -687,7 +687,7 @@ class DFRN
                                `profile`.`pub_keywords`, `profile`.`xmpp`, `profile`.`dob`
                        FROM `profile`
                                INNER JOIN `user` ON `user`.`uid` = `profile`.`uid`
-                               WHERE `profile`.`is-default` AND NOT `user`.`hidewall` AND `user`.`uid` = %d",
+                               WHERE NOT `user`.`hidewall` AND `user`.`uid` = %d",
                        intval($owner['uid'])
                );
                if (DBA::isResult($r)) {
index beb0485c46f2cf9f52ba11fc82fa4cee394164d9..bff56d5af39bbe9864bde864364758432709bdde 100644 (file)
@@ -4092,7 +4092,7 @@ class Diaspora
                        FROM `profile`
                        INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
                        INNER JOIN `contact` ON `profile`.`uid` = `contact`.`uid`
-                       WHERE `user`.`uid` = %d AND `profile`.`is-default` AND `contact`.`self` LIMIT 1",
+                       WHERE `user`.`uid` = %d AND `contact`.`self` LIMIT 1",
                        intval($uid)
                );
 
index 225c2ec2b447c5341af3237909c7076bd61c46be..dc30b596fcc2b54098e3dc7e3db1a4dacff18ced 100644 (file)
@@ -1428,7 +1428,7 @@ class OStatus
         */
        private static function addAuthor(DOMDocument $doc, array $owner, $show_profile = true)
        {
-               $profile = DBA::selectFirst('profile', ['homepage', 'publish'], ['uid' => $owner['uid'], 'is-default' => true]);
+               $profile = DBA::selectFirst('profile', ['homepage', 'publish'], ['uid' => $owner['uid']]);
                $author = $doc->createElement("author");
                XML::addElement($doc, $author, "id", $owner["url"]);
                if ($owner['account-type'] == User::ACCOUNT_TYPE_COMMUNITY) {
diff --git a/src/Repository/Notify.php b/src/Repository/Notify.php
new file mode 100644 (file)
index 0000000..2ac1485
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+
+namespace Friendica\Repository;
+
+use Exception;
+use Friendica\BaseRepository;
+use Friendica\Core\Hook;
+use Friendica\Model;
+use Friendica\Collection;
+use Friendica\Network\HTTPException\NotFoundException;
+use Friendica\Util\DateTimeFormat;
+
+class Notify extends BaseRepository
+{
+       protected static $table_name = 'notify';
+
+       protected static $model_class = Model\Notify::class;
+
+       protected static $collection_class = Collection\Notifies::class;
+
+       /**
+        * {@inheritDoc}
+        *
+        * @return Model\Notify
+        */
+       protected function create(array $data)
+       {
+               return new Model\Notify($this->dba, $this->logger, $this, $data);
+       }
+
+       /**
+        * {@inheritDoc}
+        *
+        * @return Collection\Notifies
+        */
+       public function select(array $condition = [], array $params = [])
+       {
+               $params['order'] = $params['order'] ?? ['date' => 'DESC'];
+
+               $condition = array_merge($condition, ['uid' => local_user()]);
+
+               return parent::select($condition, $params);
+       }
+
+       /**
+        * {@inheritDoc}
+        *
+        * @return Model\Notify
+        * @throws NotFoundException
+        */
+       public function getByID(int $id)
+       {
+               return $this->selectFirst(['id' => $id, 'uid' => local_user()]);
+       }
+
+       /**
+        * {@inheritDoc}
+        *
+        * @return bool true on success, false on error
+        * @throws Exception
+        */
+       public function setAllSeen(bool $seen = true)
+       {
+               return $this->dba->update('notify', ['seen' => $seen], ['uid' => local_user()]);
+       }
+
+       /**
+        * @param array $fields
+        *
+        * @return Model\Notify
+        *
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        * @throws Exception
+        */
+       public function insert(array $fields)
+       {
+               $fields['date']  = DateTimeFormat::utcNow();
+               $fields['abort'] = false;
+
+               Hook::callAll('enotify_store', $fields);
+
+               if ($fields['abort']) {
+                       $this->logger->debug('Abort adding notification entry', ['fields' => $fields]);
+                       return null;
+               }
+
+               $this->logger->debug('adding notification entry', ['fields' => $fields]);
+
+               return parent::insert($fields);
+       }
+}
index 7cbee4b83650b08303cc35d7f7f2977a884a96c5..86915701d9cf17f898000549c71dcc61d7c5fd84 100644 (file)
@@ -13,6 +13,9 @@ use Psr\Log\LoggerInterface;
 
 class PermissionSet extends BaseRepository
 {
+       /** @var int Virtual permission set id for public permission */
+       const PUBLIC = 0;
+
        protected static $table_name = 'permissionset';
 
        protected static $model_class = Model\PermissionSet::class;
@@ -47,7 +50,7 @@ class PermissionSet extends BaseRepository
        {
                if (isset($condition['id']) && !$condition['id']) {
                        return $this->create([
-                               'id' => 0,
+                               'id' => self::PUBLIC,
                                'uid' => $condition['uid'] ?? 0,
                                'allow_cid' => '',
                                'allow_gid' => '',
@@ -109,7 +112,7 @@ class PermissionSet extends BaseRepository
 
                // Public permission
                if (!$allow_cid && !$allow_gid && !$deny_cid && !$deny_gid) {
-                       return 0;
+                       return self::PUBLIC;
                }
 
                $condition = [
diff --git a/src/Repository/ProfileField.php b/src/Repository/ProfileField.php
new file mode 100644 (file)
index 0000000..b1b16dc
--- /dev/null
@@ -0,0 +1,301 @@
+<?php
+
+namespace Friendica\Repository;
+
+use Friendica\BaseModel;
+use Friendica\BaseRepository;
+use Friendica\Collection;
+use Friendica\Core\L10n;
+use Friendica\Database\Database;
+use Friendica\Database\DBA;
+use Friendica\Model;
+use Friendica\Util\ACLFormatter;
+use Friendica\Util\DateTimeFormat;
+use Psr\Log\LoggerInterface;
+
+class ProfileField extends BaseRepository
+{
+       protected static $table_name = 'profile_field';
+
+       protected static $model_class = Model\ProfileField::class;
+
+       protected static $collection_class = Collection\ProfileFields::class;
+
+       /** @var PermissionSet */
+       private $permissionSet;
+       /** @var ACLFormatter */
+       private $aclFormatter;
+       /** @var L10n */
+       private $l10n;
+
+       public function __construct(Database $dba, LoggerInterface $logger, PermissionSet $permissionSet, ACLFormatter $aclFormatter, L10n $l10n)
+       {
+               parent::__construct($dba, $logger);
+
+               $this->permissionSet = $permissionSet;
+               $this->aclFormatter = $aclFormatter;
+               $this->l10n = $l10n;
+       }
+
+       /**
+        * @param array $data
+        * @return Model\ProfileField
+        */
+       protected function create(array $data)
+       {
+               return new Model\ProfileField($this->dba, $this->logger, $this->permissionSet, $data);
+       }
+
+       /**
+        * @param array $condition
+        * @return Model\ProfileField
+        * @throws \Friendica\Network\HTTPException\NotFoundException
+        */
+       public function selectFirst(array $condition)
+       {
+               return parent::selectFirst($condition);
+       }
+
+       /**
+        * @param array $condition
+        * @param array $params
+        * @return Collection\ProfileFields
+        * @throws \Exception
+        */
+       public function select(array $condition = [], array $params = [])
+       {
+               return parent::select($condition, $params);
+       }
+
+       /**
+        * @param array $condition
+        * @param array $params
+        * @param int|null $max_id
+        * @param int|null $since_id
+        * @param int $limit
+        * @return Collection\ProfileFields
+        * @throws \Exception
+        */
+       public function selectByBoundaries(array $condition = [], array $params = [], int $max_id = null, int $since_id = null, int $limit = self::LIMIT)
+       {
+               return parent::selectByBoundaries($condition, $params, $max_id, $since_id, $limit);
+       }
+
+       /**
+        * @param int $uid Field owner user Id
+        * @return Collection\ProfileFields
+        * @throws \Exception
+        */
+       public function selectByUserId(int $uid)
+       {
+               return $this->select(
+                       ['uid' => $uid],
+                       ['order' => ['order']]
+               );
+       }
+
+       /**
+        * Retrieve all custom profile field a given contact is able to access to, including public profile fields.
+        *
+        * @param int $cid Private contact id, must be owned by $uid
+        * @param int $uid Field owner user id
+        * @return Collection\ProfileFields
+        * @throws \Exception
+        */
+       public function selectByContactId(int $cid, int $uid)
+       {
+               $permissionSets = $this->permissionSet->selectByContactId($cid, $uid);
+
+               $psids = $permissionSets->column('id');
+
+               // Includes public custom fields
+               $psids[] = 0;
+
+               return $this->select(
+                       ['uid' => $uid, 'psid' => $psids],
+                       ['order' => ['order']]
+               );
+       }
+
+       /**
+        * @param array $fields
+        * @return Model\ProfileField|bool
+        * @throws \Exception
+        */
+       public function insert(array $fields)
+       {
+               $fields['created'] = DateTimeFormat::utcNow();
+               $fields['edited']  = DateTimeFormat::utcNow();
+
+               return parent::insert($fields);
+       }
+
+       /**
+        * @param Model\ProfileField $model
+        * @return bool
+        * @throws \Exception
+        */
+       public function update(BaseModel $model)
+       {
+               $model->edited = DateTimeFormat::utcNow();
+
+               return parent::update($model);
+       }
+       
+       /**
+        * @param int                      $uid                User Id
+        * @param Collection\ProfileFields $profileFields      Collection of existing profile fields
+        * @param array                    $profileFieldInputs Array of profile field form inputs indexed by profile field id
+        * @param array                    $profileFieldOrder  List of profile field id in order
+        * @return Collection\ProfileFields
+        * @throws \Exception
+        */
+       public function updateCollectionFromForm(int $uid, Collection\ProfileFields $profileFields, array $profileFieldInputs, array $profileFieldOrder)
+       {
+               // Returns an associative array of id => order values
+               $profileFieldOrder = array_flip($profileFieldOrder);
+
+               // Creation of the new field
+               if (!empty($profileFieldInputs['new']['label'])) {
+                       $psid = $this->permissionSet->getIdFromACL(
+                               $uid,
+                               $this->aclFormatter->toString($profileFieldInputs['new']['contact_allow'] ?? ''),
+                               $this->aclFormatter->toString($profileFieldInputs['new']['group_allow'] ?? ''),
+                               $this->aclFormatter->toString($profileFieldInputs['new']['contact_deny'] ?? ''),
+                               $this->aclFormatter->toString($profileFieldInputs['new']['group_deny'] ?? '')
+                       );
+
+                       $newProfileField = $this->insert([
+                               'uid' => $uid,
+                               'label' => $profileFieldInputs['new']['label'],
+                               'value' => $profileFieldInputs['new']['value'],
+                               'psid' => $psid,
+                               'order' => $profileFieldOrder['new'],
+                       ]);
+
+                       $profileFieldInputs[$newProfileField->id] = $profileFieldInputs['new'];
+                       $profileFieldOrder[$newProfileField->id] = $profileFieldOrder['new'];
+
+                       $profileFields[] = $newProfileField;
+               }
+
+               unset($profileFieldInputs['new']);
+               unset($profileFieldOrder['new']);
+
+               // Prunes profile field whose label has been emptied
+               $profileFields = $profileFields->filter(function (Model\ProfileField $profileField) use (&$profileFieldInputs, &$profileFieldOrder) {
+                       $keepModel = !isset($profileFieldInputs[$profileField->id]) || !empty($profileFieldInputs[$profileField->id]['label']);
+
+                       if (!$keepModel) {
+                               unset($profileFieldInputs[$profileField->id]);
+                               unset($profileFieldOrder[$profileField->id]);
+                               $this->delete($profileField);
+                       }
+
+                       return $keepModel;
+               });
+
+               // Regenerates the order values if items were deleted
+               $profileFieldOrder = array_flip(array_keys($profileFieldOrder));
+
+               // Update existing profile fields from form values
+               $profileFields = $profileFields->map(function (Model\ProfileField $profileField) use ($uid, &$profileFieldInputs, &$profileFieldOrder) {
+                       if (isset($profileFieldInputs[$profileField->id]) && isset($profileFieldOrder[$profileField->id])) {
+                               $psid = $this->permissionSet->getIdFromACL(
+                                       $uid,
+                                       $this->aclFormatter->toString($profileFieldInputs[$profileField->id]['contact_allow'] ?? ''),
+                                       $this->aclFormatter->toString($profileFieldInputs[$profileField->id]['group_allow'] ?? ''),
+                                       $this->aclFormatter->toString($profileFieldInputs[$profileField->id]['contact_deny'] ?? ''),
+                                       $this->aclFormatter->toString($profileFieldInputs[$profileField->id]['group_deny'] ?? '')
+                               );
+
+                               $profileField->psid  = $psid;
+                               $profileField->label = $profileFieldInputs[$profileField->id]['label'];
+                               $profileField->value = $profileFieldInputs[$profileField->id]['value'];
+                               $profileField->order = $profileFieldOrder[$profileField->id];
+
+                               unset($profileFieldInputs[$profileField->id]);
+                               unset($profileFieldOrder[$profileField->id]);
+                       }
+
+                       return $profileField;
+               });
+
+               return $profileFields;
+       }
+
+       /**
+        * Migrates a legacy profile to the new slimmer profile with extra custom fields.
+        * Multi profiles are converted to ACl-protected custom fields and deleted.
+        *
+        * @param array $profile Profile table row
+        * @throws \Exception
+        */
+       public function migrateFromLegacyProfile(array $profile)
+       {
+               // Already processed, aborting
+               if ($profile['is-default'] === null) {
+                       return;
+               }
+
+               if (!$profile['is-default']) {
+                       $contacts = Model\Contact::selectToArray(['id'], ['uid' => $profile['uid'], 'profile-id' => $profile['id']]);
+                       if (!count($contacts)) {
+                               // No contact visibility selected defaults to user-only permission
+                               $contacts = Model\Contact::selectToArray(['id'], ['uid' => $profile['uid'], 'self' => true]);
+                       }
+
+                       $allow_cid = $this->aclFormatter->toString(array_column($contacts, 'id'));
+               }
+
+               $psid = $this->permissionSet->getIdFromACL($profile['uid'], $allow_cid ?? '');
+
+               $order = 1;
+
+               $custom_fields = [
+                       'hometown'  => $this->l10n->t('Hometown:'),
+                       'gender'    => $this->l10n->t('Gender:'),
+                       'marital'   => $this->l10n->t('Marital Status:'),
+                       'with'      => $this->l10n->t('With:'),
+                       'howlong'   => $this->l10n->t('Since:'),
+                       'sexual'    => $this->l10n->t('Sexual Preference:'),
+                       'politic'   => $this->l10n->t('Political Views:'),
+                       'religion'  => $this->l10n->t('Religious Views:'),
+                       'likes'     => $this->l10n->t('Likes:'),
+                       'dislikes'  => $this->l10n->t('Dislikes:'),
+                       'about'     => $this->l10n->t('About:'),
+                       'summary'   => $this->l10n->t('Summary'),
+                       'music'     => $this->l10n->t('Musical interests'),
+                       'book'      => $this->l10n->t('Books, literature'),
+                       'tv'        => $this->l10n->t('Television'),
+                       'film'      => $this->l10n->t('Film/dance/culture/entertainment'),
+                       'interest'  => $this->l10n->t('Hobbies/Interests'),
+                       'romance'   => $this->l10n->t('Love/romance'),
+                       'work'      => $this->l10n->t('Work/employment'),
+                       'education' => $this->l10n->t('School/education'),
+                       'contact'   => $this->l10n->t('Contact information and Social Networks'),
+               ];
+
+               foreach ($custom_fields as $field => $label) {
+                       if (!empty($profile[$field]) && $profile[$field] > DBA::NULL_DATE && $profile[$field] > DBA::NULL_DATETIME) {
+                               $this->insert([
+                                       'uid' => $profile['uid'],
+                                       'psid' => $psid,
+                                       'order' => $order++,
+                                       'label' => trim($label, ':'),
+                                       'value' => $profile[$field],
+                               ]);
+                       }
+
+                       $profile[$field] = null;
+               }
+
+               if ($profile['is-default']) {
+                       $profile['profile-name'] = null;
+                       $profile['is-default'] = null;
+                       $this->dba->update('profile', $profile, ['id' => $profile['id']]);
+               } elseif (!empty($profile['id'])) {
+                       $this->dba->delete('profile', ['id' => $profile['id']]);
+               }
+       }
+}
index 41835b6609b7abe210cb91836645d71d1df2ee3f..8f6dc09e1614d0839734867a6e3045871d563ca9 100644 (file)
@@ -4,34 +4,46 @@
  */
 namespace Friendica\Util;
 
+use Friendica\App;
+use Friendica\Core\Config\IConfig;
 use Friendica\Core\Hook;
-use Friendica\Core\Logger;
-use Friendica\DI;
+use Friendica\Core\PConfig\IPConfig;
+use Friendica\Network\HTTPException\InternalServerErrorException;
+use Friendica\Object\EMail\IEmail;
 use Friendica\Protocol\Email;
+use Psr\Log\LoggerInterface;
 
 /**
  * class to handle emailing
  */
 class Emailer
 {
+       /** @var IConfig */
+       private $config;
+       /** @var IPConfig */
+       private $pConfig;
+       /** @var LoggerInterface */
+       private $logger;
+       /** @var App\BaseURL */
+       private $baseUrl;
+
+       public function __construct(IConfig $config, IPConfig $pConfig, App\BaseURL $baseURL, LoggerInterface $logger)
+       {
+               $this->config      = $config;
+               $this->pConfig     = $pConfig;
+               $this->logger      = $logger;
+               $this->baseUrl     = $baseURL;
+       }
+
        /**
         * Send a multipart/alternative message with Text and HTML versions
         *
-        * @param array $params parameters
-        *                      fromName             name of the sender
-        *                      fromEmail            email of the sender
-        *                      replyTo              address to direct responses
-        *                      toEmail              destination email address
-        *                      messageSubject       subject of the message
-        *                      htmlVersion          html version of the message
-        *                      textVersion          text only version of the message
-        *                      additionalMailHeader additions to the SMTP mail header
-        *                      optional             uid user id of the destination user
+        * @param IEmail $email The email to send
         *
         * @return bool
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        * @throws InternalServerErrorException
         */
-       public static function send(array $params)
+       public function send(IEmail $email)
        {
                $params['sent'] = false;
 
@@ -42,61 +54,63 @@ class Emailer
                }
 
                $email_textonly = false;
-               if (!empty($params['uid'])) {
-                       $email_textonly = DI::pConfig()->get($params['uid'], "system", "email_textonly");
+               if (!empty($email->getRecipientUid())) {
+                       $email_textonly = $this->pConfig->get($email->getRecipientUid(), 'system', 'email_textonly');
                }
 
-               $fromName = Email::encodeHeader(html_entity_decode($params['fromName'], ENT_QUOTES, 'UTF-8'), 'UTF-8');
-               $messageSubject = Email::encodeHeader(html_entity_decode($params['messageSubject'], ENT_QUOTES, 'UTF-8'), 'UTF-8');
+               $fromName       = Email::encodeHeader(html_entity_decode($email->getFromName(), ENT_QUOTES, 'UTF-8'), 'UTF-8');
+               $fromAddress      = $email->getFromAddress();
+               $replyTo        = $email->getReplyTo();
+               $messageSubject = Email::encodeHeader(html_entity_decode($email->getSubject(), ENT_QUOTES, 'UTF-8'), 'UTF-8');
 
                // generate a mime boundary
-               $mimeBoundary   =rand(0, 9)."-"
-                               .rand(100000000, 999999999)."-"
-                               .rand(100000000, 999999999)."=:"
-                               .rand(10000, 99999);
+               $mimeBoundary = rand(0, 9) . '-'
+                               . rand(100000000, 999999999) . '-'
+                               . rand(100000000, 999999999) . '=:'
+                               . rand(10000, 99999);
 
                // generate a multipart/alternative message header
-               $messageHeader = ($params['additionalMailHeader'] ?? '') .
-                                               "From: $fromName <{$params['fromEmail']}>\n" .
-                                               "Reply-To: $fromName <{$params['replyTo']}>\n" .
-                                               "MIME-Version: 1.0\n" .
-                                               "Content-Type: multipart/alternative; boundary=\"{$mimeBoundary}\"";
+               $messageHeader = $email->getAdditionalMailHeader() .
+                                "From: $fromName <{$fromAddress}>\n" .
+                                "Reply-To: $fromName <{$replyTo}>\n" .
+                                "MIME-Version: 1.0\n" .
+                                "Content-Type: multipart/alternative; boundary=\"{$mimeBoundary}\"";
 
                // assemble the final multipart message body with the text and html types included
-               $textBody       =       chunk_split(base64_encode($params['textVersion']));
-               $htmlBody       =       chunk_split(base64_encode($params['htmlVersion']));
-               $multipartMessageBody = "--" . $mimeBoundary . "\n" .                                   // plain text section
-                                                               "Content-Type: text/plain; charset=UTF-8\n" .
-                                                               "Content-Transfer-Encoding: base64\n\n" .
-                                                               $textBody . "\n";
-
-               if (!$email_textonly && !is_null($params['htmlVersion'])) {
+               $textBody             = chunk_split(base64_encode($email->getMessage(true)));
+               $htmlBody             = chunk_split(base64_encode($email->getMessage()));
+               $multipartMessageBody = "--" . $mimeBoundary . "\n" .                    // plain text section
+                                       "Content-Type: text/plain; charset=UTF-8\n" .
+                                       "Content-Transfer-Encoding: base64\n\n" .
+                                       $textBody . "\n";
+
+               if (!$email_textonly && !is_null($email->getMessage())) {
                        $multipartMessageBody .=
-                               "--" . $mimeBoundary . "\n" .                           // text/html section
+                               "--" . $mimeBoundary . "\n" .                // text/html section
                                "Content-Type: text/html; charset=UTF-8\n" .
                                "Content-Transfer-Encoding: base64\n\n" .
                                $htmlBody . "\n";
                }
                $multipartMessageBody .=
-                       "--" . $mimeBoundary . "--\n";                                  // message ending
+                       "--" . $mimeBoundary . "--\n";                    // message ending
 
-               if (DI::config()->get("system", "sendmail_params", true)) {
-                       $sendmail_params = '-f ' . $params['fromEmail'];
+               if ($this->config->get('system', 'sendmail_params', true)) {
+                       $sendmail_params = '-f ' . $fromAddress;
                } else {
                        $sendmail_params = null;
                }
 
                // send the message
                $hookdata = [
-                       'to' => $params['toEmail'],
-                       'subject' => $messageSubject,
-                       'body' => $multipartMessageBody,
-                       'headers' => $messageHeader,
+                       'to'         => $email->getToAddress(),
+                       'subject'    => $messageSubject,
+                       'body'       => $multipartMessageBody,
+                       'headers'    => $messageHeader,
                        'parameters' => $sendmail_params,
-                       'sent' => false,
+                       'sent'       => false,
                ];
 
-               Hook::callAll("emailer_send", $hookdata);
+               Hook::callAll('emailer_send', $hookdata);
 
                if ($hookdata['sent']) {
                        return true;
@@ -109,8 +123,8 @@ class Emailer
                        $hookdata['headers'],
                        $hookdata['parameters']
                );
-               Logger::log("header " . 'To: ' . $params['toEmail'] . "\n" . $messageHeader, Logger::DEBUG);
-               Logger::log("return value " . (($res)?"true":"false"), Logger::DEBUG);
+               $this->logger->debug('header ' . 'To: ' . $email->getToAddress() . '\n' . $messageHeader);
+               $this->logger->debug('return value ' . (($res) ? 'true' : 'false'));
                return $res;
        }
 }
index 4d5393dd84dcd27717c2f77b25491804b444c443..ac9aeae5b974630e5671706bbd19b6eaa95a9d22 100644 (file)
@@ -46,7 +46,7 @@ class Directory
                $r = q("SELECT `url` FROM `contact`
                        INNER JOIN `profile` ON `profile`.`uid` = `contact`.`uid`
                        INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
-                               WHERE `contact`.`self` AND `profile`.`net-publish` AND `profile`.`is-default` AND
+                               WHERE `contact`.`self` AND `profile`.`net-publish` AND
                                        NOT `user`.`account_expired` AND `user`.`verified`");
 
                if (DBA::isResult($r)) {
index 49934c63cf2324ea86d6e5d40b175e4f45e59cba..87cfdd11c6330d5a222ba0dce9790b9afad9952e 100755 (executable)
@@ -34,7 +34,7 @@
 use Friendica\Database\DBA;
 
 if (!defined('DB_UPDATE_VERSION')) {
-       define('DB_UPDATE_VERSION', 1330);
+       define('DB_UPDATE_VERSION', 1332);
 }
 
 return [
@@ -277,7 +277,7 @@ return [
                        "reason" => ["type" => "text", "comment" => ""],
                        "closeness" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "99", "comment" => ""],
                        "info" => ["type" => "mediumtext", "comment" => ""],
-                       "profile-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "comment" => ""],
+                       "profile-id" => ["type" => "int unsigned", "comment" => "Deprecated"],
                        "bdyear" => ["type" => "varchar(4)", "not null" => "1", "default" => "", "comment" => ""],
                        "bd" => ["type" => "date", "not null" => "1", "default" => DBA::NULL_DATE, "comment" => ""],
                        "notify_new_posts" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
@@ -1084,8 +1084,8 @@ return [
                "fields" => [
                        "id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
                        "uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "relation" => ["user" => "uid"], "comment" => "Owner User id"],
-                       "profile-name" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "Name of the profile"],
-                       "is-default" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Mark this profile as default profile"],
+                       "profile-name" => ["type" => "varchar(255)", "comment" => "Deprecated"],
+                       "is-default" => ["type" => "boolean", "comment" => "Deprecated"],
                        "hide-friends" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Hide friend list from viewers of this profile"],
                        "name" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
                        "pdesc" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "Title or description"],
@@ -1095,29 +1095,29 @@ return [
                        "region" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
                        "postal-code" => ["type" => "varchar(32)", "not null" => "1", "default" => "", "comment" => ""],
                        "country-name" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
-                       "hometown" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
-                       "gender" => ["type" => "varchar(32)", "not null" => "1", "default" => "", "comment" => ""],
-                       "marital" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
-                       "with" => ["type" => "text", "comment" => ""],
-                       "howlong" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""],
-                       "sexual" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
-                       "politic" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
-                       "religion" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
+                       "hometown" => ["type" => "varchar(255)", "comment" => "Deprecated"],
+                       "gender" => ["type" => "varchar(32)", "comment" => "Deprecated"],
+                       "marital" => ["type" => "varchar(255)", "comment" => "Deprecated"],
+                       "with" => ["type" => "text", "comment" => "Deprecated"],
+                       "howlong" => ["type" => "datetime", "comment" => "Deprecated"],
+                       "sexual" => ["type" => "varchar(255)", "comment" => "Deprecated"],
+                       "politic" => ["type" => "varchar(255)", "comment" => "Deprecated"],
+                       "religion" => ["type" => "varchar(255)", "comment" => "Deprecated"],
                        "pub_keywords" => ["type" => "text", "comment" => ""],
                        "prv_keywords" => ["type" => "text", "comment" => ""],
-                       "likes" => ["type" => "text", "comment" => ""],
-                       "dislikes" => ["type" => "text", "comment" => ""],
-                       "about" => ["type" => "text", "comment" => ""],
-                       "summary" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
-                       "music" => ["type" => "text", "comment" => ""],
-                       "book" => ["type" => "text", "comment" => ""],
-                       "tv" => ["type" => "text", "comment" => ""],
-                       "film" => ["type" => "text", "comment" => ""],
-                       "interest" => ["type" => "text", "comment" => ""],
-                       "romance" => ["type" => "text", "comment" => ""],
-                       "work" => ["type" => "text", "comment" => ""],
-                       "education" => ["type" => "text", "comment" => ""],
-                       "contact" => ["type" => "text", "comment" => ""],
+                       "likes" => ["type" => "text", "comment" => "Deprecated"],
+                       "dislikes" => ["type" => "text", "comment" => "Deprecated"],
+                       "about" => ["type" => "text", "comment" => "Deprecated"],
+                       "summary" => ["type" => "varchar(255)", "comment" => "Deprecated"],
+                       "music" => ["type" => "text", "comment" => "Deprecated"],
+                       "book" => ["type" => "text", "comment" => "Deprecated"],
+                       "tv" => ["type" => "text", "comment" => "Deprecated"],
+                       "film" => ["type" => "text", "comment" => "Deprecated"],
+                       "interest" => ["type" => "text", "comment" => "Deprecated"],
+                       "romance" => ["type" => "text", "comment" => "Deprecated"],
+                       "work" => ["type" => "text", "comment" => "Deprecated"],
+                       "education" => ["type" => "text", "comment" => "Deprecated"],
+                       "contact" => ["type" => "text", "comment" => "Deprecated"],
                        "homepage" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
                        "xmpp" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
                        "photo" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
@@ -1145,6 +1145,25 @@ return [
                        "PRIMARY" => ["id"],
                ]
        ],
+       "profile_field" => [
+               "comment" => "Custom profile fields",
+               "fields" => [
+                       "id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
+                       "uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "relation" => ["user" => "uid"], "comment" => "Owner user id"],
+                       "order" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "1", "comment" => "Field ordering per user"],
+                       "psid" => ["type" => "int unsigned", "relation" => ["permissionset" => "id"], "comment" => "ID of the permission set of this profile field - 0 = public"],
+                       "label" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "Label of the field"],
+                       "value" => ["type" => "text", "comment" => "Value of the field"],
+                       "created" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "creation time"],
+                       "edited" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "last edit time"],
+               ],
+               "indexes" => [
+                       "PRIMARY" => ["id"],
+                       "uid" => ["uid"],
+                       "order" => ["order"],
+                       "psid" => ["psid"],
+               ]
+       ],
        "push_subscriber" => [
                "comment" => "Used for OStatus: Contains feed subscribers",
                "fields" => [
index 05f2599561a90ed777aa9d672f85937d1b236ad5..a4fc823940d2b557e05fa0b4941746e5100820b3 100644 (file)
@@ -167,10 +167,20 @@ return [
        '/nodeinfo/{version}' => [Module\NodeInfo::class,        [R::GET]],
        '/nogroup'            => [Module\Group::class,           [R::GET]],
 
-       '/notify'         => [
-               '[/]'            => [Module\Notifications\Notify::class, [R::GET]],
-               '/view/{id:\d+}' => [Module\Notifications\Notify::class, [R::GET]],
-               '/mark/all'      => [Module\Notifications\Notify::class, [R::GET]],
+       '/notifications' => [
+               '/network[/json]'    => [Module\Notifications\Notifications::class, [R::GET, R::POST]],
+               '/system[/json]'     => [Module\Notifications\Notifications::class, [R::GET, R::POST]],
+               '/personal[/json]'   => [Module\Notifications\Notifications::class, [R::GET, R::POST]],
+               '/home[/json]'       => [Module\Notifications\Notifications::class, [R::GET, R::POST]],
+               '/intros[/json]'     => [Module\Notifications\Introductions::class, [R::GET, R::POST]],
+               '/intros/all[/json]' => [Module\Notifications\Introductions::class, [R::GET, R::POST]],
+               '/intros/{contact:\d+}[/json]' => [Module\Notifications\Introductions::class, [R::GET, R::POST]],
+       ],
+
+       '/notification'         => [
+               '[/]'            => [Module\Notifications\Notification::class, [R::GET]],
+               '/view/{id:\d+}' => [Module\Notifications\Notification::class, [R::GET]],
+               '/mark/all'      => [Module\Notifications\Notification::class, [R::GET]],
        ],
        '/objects/{guid}' => [Module\Objects::class, [R::GET]],
 
@@ -195,10 +205,10 @@ return [
        '/probe'             => [Module\Debug\Probe::class,  [R::GET]],
 
        '/profile' => [
-               '/{nickname}'                                                 => [Module\Profile::class,          [R::GET]],
-               '/{nickname}/{to:\d{4}-\d{2}-\d{2}}/{from:\d{4}-\d{2}-\d{2}}' => [Module\Profile::class,          [R::GET]],
-               '/{nickname}/contacts[/{type}]'                               => [Module\Profile\Contacts::class, [R::GET]],
-               '/{profile:\d+}/view'                                         => [Module\Profile::class,          [R::GET]],
+               '/{nickname}'                                         => [Module\Profile\Index::class,    [R::GET]],
+               '/{nickname}/profile'                                 => [Module\Profile\Profile::class,  [R::GET]],
+               '/{nickname}/contacts[/{type}]'                       => [Module\Profile\Contacts::class, [R::GET]],
+               '/{nickname}/status[/{category}[/{date1}[/{date2}]]]' => [Module\Profile\Status::class,   [R::GET]],
        ],
 
        '/proxy' => [
@@ -229,6 +239,7 @@ return [
                ],
                '/delegation[/{action}/{user_id}]' => [Module\Settings\Delegation::class,       [R::GET, R::POST]],
                '/profile' => [
+                       '[/]'                  => [Module\Settings\Profile\Index::class,       [R::GET, R::POST]],
                        '/photo[/new]'         => [Module\Settings\Profile\Photo\Index::class, [R::GET, R::POST]],
                        '/photo/crop/{guid}'   => [Module\Settings\Profile\Photo\Crop::class,  [R::GET, R::POST]],
                ],
@@ -244,6 +255,9 @@ return [
        '/starred/{item:\d+}'            => [Module\Starred::class,               [R::GET]],
        '/toggle_mobile'                 => [Module\ToggleMobile::class,          [R::GET]],
        '/tos'                           => [Module\Tos::class,                   [R::GET]],
+
+       '/update_profile'                => [Module\Update\Profile::class,        [R::GET]],
+
        '/view/theme/{theme}/style.pcss' => [Module\Theme::class,                 [R::GET]],
        '/viewsrc/{item:\d+}'            => [Module\Debug\ItemBody::class,        [R::GET]],
        '/webfinger'                     => [Module\Debug\WebFinger::class,       [R::GET]],
index fc34df95754fcba85995aad7e34ea8877fc28448..6d4b8770d0c5a4914845722e2b3c0b7363b289ee 100644 (file)
@@ -159,7 +159,7 @@ class RouterTest extends TestCase
                                        '/post' => [
                                                '/it' => [Module\NodeInfo::class, [Router::POST]],
                                        ],
-                                       '/double' => [Module\Profile::class, [Router::GET, Router::POST]]
+                                       '/double' => [Module\Profile\Index::class, [Router::GET, Router::POST]]
                                ],
                        ],
                ];
@@ -177,7 +177,7 @@ class RouterTest extends TestCase
                $this->assertEquals(Module\Home::class, $router->getModuleClass('/'));
                $this->assertEquals(Module\Friendica::class, $router->getModuleClass('/group/route'));
                $this->assertEquals(Module\Xrd::class, $router->getModuleClass('/group2/group3/route'));
-               $this->assertEquals(Module\Profile::class, $router->getModuleClass('/double'));
+               $this->assertEquals(Module\Profile\Index::class, $router->getModuleClass('/double'));
        }
 
        /**
@@ -191,6 +191,6 @@ class RouterTest extends TestCase
 
                // Don't find GET
                $this->assertEquals(Module\NodeInfo::class, $router->getModuleClass('/post/it'));
-               $this->assertEquals(Module\Profile::class, $router->getModuleClass('/double'));
+               $this->assertEquals(Module\Profile\Index::class, $router->getModuleClass('/double'));
        }
 }
index 22ed4ae9e3cfe3027a4f7edb58f1cfeb31375bcb..f86fea8dfd4c227b34327acb36d45fdf2a4bb312 100644 (file)
@@ -430,3 +430,18 @@ function update_1330()
 
        return Update::SUCCESS;
 }
+
+function update_1332()
+{
+       $condition = ["`is-default` IS NOT NULL"];
+       $profiles = DBA::select('profile', [], $condition);
+
+       while ($profile = DBA::fetch($profiles)) {
+               DI::profileField()->migrateFromLegacyProfile($profile);
+       }
+       DBA::close($profiles);
+
+       DBA::update('contact', ['profile-id' => null], ['`profile-id` IS NOT NULL']);
+
+       return Update::SUCCESS;
+}
index 0eaf4482dccce4f31f0314dbe0ad25a13778d40d..a50d10de409149bbe28194fcc071a7e489779697 100644 (file)
@@ -274,7 +274,7 @@ code, key {
 }
 
 /* notifications unseen */
-.notify-unseen { background-color: #cceeFF; }
+.notification-unseen { background-color: #cceeFF; }
 
 /* autocomplete popup */
 ul.acpopup {
@@ -639,3 +639,37 @@ span.emoji.mastodon img {
     display: none;
   }
 }
+
+/* Profile Settings Custom Fields */
+body.dragging, body.dragging * {
+       cursor: ns-resize !important;
+}
+
+.dragged {
+       position: absolute;
+       opacity: 0.5;
+       z-index: 2000;
+}
+
+#profile-custom-fields > fieldset > legend {
+       cursor: ns-resize;
+}
+
+#profile-custom-fields div.placeholder {
+       position: relative;
+       margin: 0;
+       padding: 0;
+       border-top: 1px dotted black;
+}
+#profile-custom-fields div.placeholder:before {
+       position: absolute;
+       content: "";
+       width: 0;
+       height: 0;
+       margin-top: -7px;
+       left: -7px;
+       top: -1px;
+       border: 7px solid transparent;
+       border-left-color: black;
+       border-right: none;
+}
index 81d26120e7c849922c6411db893e1f4caca731f9..95ee4b8ed91e576141a84f6b702a8acab425d4de 100644 (file)
@@ -245,7 +245,7 @@ $(function() {
                        window.location.href=window.location.href
                }
 
-               ['net', 'home', 'intro', 'mail', 'events', 'birthdays', 'notify'].forEach(function(type) {
+               ['net', 'home', 'intro', 'mail', 'events', 'birthdays', 'notification'].forEach(function(type) {
                        var number = data[type];
                        if (number == 0) {
                                number = '';
@@ -299,19 +299,19 @@ $(function() {
                        var notification_id = 0;
 
                        // Insert notifs into the notifications-menu
-                       $(data.notifications).each(function(key, notif) {
-                               var text = notif.message.format('<span class="contactname">' + notif.name + '</span>');
-                               var contact = ('<a href="' + notif.url + '"><span class="contactname">' + notif.name + '</span></a>');
-                               var seenclass = (notif.seen == 1) ? "notify-seen" : "notify-unseen";
+                       $(data.notifications).each(function(key, notification) {
+                               var text = notification.message.format('<span class="contactname">' + notification.name + '</span>');
+                               var contact = ('<a href="' + notification.url + '"><span class="contactname">' + notification.name + '</span></a>');
+                               var seenclass = (notification.seen == 1) ? "notification-seen" : "notification-unseen";
                                var html = notifications_tpl.format(
-                                       notif.href,                     // {0}  // link to the source
-                                       notif.photo,                    // {1}  // photo of the contact
+                                       notification.href,                     // {0}  // link to the source
+                                       notification.photo,                    // {1}  // photo of the contact
                                        text,                           // {2}  // preformatted text (autor + text)
-                                       notif.date,                     // {3}  // date of notification (time ago)
+                                       notification.date,                     // {3}  // date of notification (time ago)
                                        seenclass,                      // {4}  // visited status of the notification
-                                       new Date(notif.timestamp*1000), // {5}  // date of notification
-                                       notif.url,                      // {6}  // profile url of the contact
-                                       notif.message.format(contact),  // {7}  // preformatted html (text including author profile url)
+                                       new Date(notification.timestamp*1000), // {5}  // date of notification
+                                       notification.url,                      // {6}  // profile url of the contact
+                                       notification.message.format(contact),  // {7}  // preformatted html (text including author profile url)
                                        ''                              // {8}  // Deprecated
                                );
                                nnm.append(html);
@@ -349,7 +349,7 @@ $(function() {
                        });
                }
 
-               var notif = data['notify'];
+               var notif = data['notification'];
                if (notif > 0) {
                        $("#nav-notifications-linkmenu").addClass("on");
                } else {
@@ -948,8 +948,8 @@ function checkboxhighlight(box) {
        }
 }
 
-function notifyMarkAll() {
-       $.get('notify/mark/all', function(data) {
+function notificationMarkAll() {
+       $.get('notification/mark/all', function(data) {
                if (timer) {
                        clearTimeout(timer);
                }
diff --git a/view/js/module/settings/profile/index.js b/view/js/module/settings/profile/index.js
new file mode 100644 (file)
index 0000000..1177e51
--- /dev/null
@@ -0,0 +1,13 @@
+$(function () {
+       $("#profile-custom-fields").sortable({
+               containerSelector: 'div#profile-custom-fields',
+               handle: 'legend',
+               itemSelector: 'fieldset',
+               placeholder: '<div class="placeholder"></div>',
+               onDrag: function($item, position, _super, event) {
+                       delete position['left'];
+                       $item.css(position);
+                       event.preventDefault();
+               }
+       });
+});
index d78d4162efa69042035619525cae1bae02938f92..5f582e066c56e0511c6913c73b126b6a0eb92bc2 100644 (file)
                                </div>
                                <div id="contact-info-end"></div>
                                {{/if}}
-
-                               {{if $profile_select}}
-                                       <div id="contact-edit-profile-select-text">
-                                       <h4>{{$lbl_vis1}}</h4>
-                                       <p>{{$lbl_vis2}}</p> 
-                                       </div>
-                                       {{$profile_select nofilter}}
-                                       <div id="contact-edit-profile-select-end"></div>
-                               {{/if}}
                        </div>
 
                        <input class="contact-edit-submit" type="submit" name="submit" value="{{$submit}}" />
diff --git a/view/templates/intros.tpl b/view/templates/intros.tpl
deleted file mode 100644 (file)
index 1f7f838..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-<h2>{{$header}}</h2>
-
-<div class="intro-wrapper" id="intro-{{$contact_id}}" >
-
-<p class="intro-desc">{{$str_notifytype}} {{$notify_type}}</p>
-<img id="photo-{{$contact_id}}" class="intro-photo" src="{{$photo}}" width="175" height=175" title="{{$fullname}}" alt="{{$fullname}}" />
-<dl><dt>{{$lbl_url}}</dt><dd><a target="blank" href="{{$zrl}}">{{$url}}</a></dd></dl>
-{{if $location}}<dl><dt>{{$lbl_location}}</dt><dd>{{$location}}</dd></dl>{{/if}}
-{{if $gender}}<dl><dt>{{$lbl_gender}}</dt><dd>{{$gender}}</dd></dl>{{/if}}
-{{if $keywords}}<dl><dt>{{$lbl_keywords}}</dt><dd>{{$keywords}}</dd></dl>{{/if}}
-{{if $about}}<dl><dt>{{$lbl_about}}</dt><dd>{{$about nofilter}}</dd></dl>{{/if}}
-<div class="intro-knowyou">{{$lbl_knowyou}} {{$knowyou}}</div>
-<div class="intro-note" id="intro-note-{{$contact_id}}">{{$note}}</div>
-<div class="intro-wrapper-end" id="intro-wrapper-end-{{$contact_id}}"></div>
-<form class="intro-form" action="notifications/{{$intro_id}}" method="post">
-<input class="intro-submit-ignore" type="submit" name="submit" value="{{$ignore}}" />
-{{if $discard}}<input class="intro-submit-discard" type="submit" name="submit" value="{{$discard}}" />{{/if}}
-</form>
-<div class="intro-form-end"></div>
-
-<form class="intro-approve-form" action="{{$action}}" method="post">
-{{include file="field_checkbox.tpl" field=$hidden}}
-<input type="hidden" name="dfrn_id" value="{{$dfrn_id}}" >
-<input type="hidden" name="intro_id" value="{{$intro_id}}" >
-<input type="hidden" name="contact_id" value="{{$contact_id}}" >
-
-{{$dfrn_text nofilter}}
-
-<input class="intro-submit-approve" type="submit" name="submit" value="{{$approve}}" />
-</form>
-</div>
-<div class="intro-end"></div>
index b9c2cf1f12b195193deea4d02a798b33358c692e..07e9469a8c6bea32fafcba8887363f78a2269c54 100644 (file)
@@ -34,7 +34,7 @@
        <a accesskey="c" id="nav-community-link" class="nav-commlink {{$nav.community.2}} {{$sel.community}}" href="{{$nav.community.0}}" title="{{$nav.community.3}}" >{{$nav.community.1}}</a>
        {{/if}}
        {{if $nav.introductions}}
-       <a id="nav-notify-link" class="nav-commlink {{$nav.introductions.2}} {{$sel.introductions}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >{{$nav.introductions.1}}</a>
+       <a id="nav-notification-link" class="nav-commlink {{$nav.introductions.2}} {{$sel.introductions}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >{{$nav.introductions.1}}</a>
        <span id="intro-update" class="nav-ajax-left"></span>
        {{/if}}
        {{if $nav.messages}}
 
                {{if $nav.notifications}}
                        <a accesskey="f" id="nav-notifications-linkmenu" class="nav-commlink" href="{{$nav.notifications.0}}" rel="#nav-notifications-menu" title="{{$nav.notifications.1}}">{{$nav.notifications.1}}</a>
-                               <span id="notify-update" class="nav-ajax-left"></span>
+                               <span id="notification-update" class="nav-ajax-left"></span>
                                <ul id="nav-notifications-menu" class="menu-popup">
                                        <li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
-                                       <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
+                                       <li id="nav-notifications-mark-all"><a href="#" onclick="notificationMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
                                        <li class="empty">{{$emptynotifications}}</li>
                                </ul>
                {{/if}}         
diff --git a/view/templates/netfriend.tpl b/view/templates/netfriend.tpl
deleted file mode 100644 (file)
index 465d7eb..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-
-<div class="intro-approve-as-friend-desc">
-  <p>{{$approve_as1}}</p>
-  <p>{{$approve_as2}}</p>
-  <p>{{$approve_as3}}</p>
-</div>
-
-<div class="intro-approve-as-friend-wrapper">
-       <label class="intro-approve-as-friend-label" for="intro-approve-as-friend-{{$intro_id}}">{{$as_friend}}</label>
-       <input type="radio" name="duplex" id="intro-approve-as-friend-{{$intro_id}}" class="intro-approve-as-friend" {{$friend_selected}} value="1" />
-       <div class="intro-approve-friend-break" ></div> 
-</div>
-<div class="intro-approve-as-friend-end"></div>
-<div class="intro-approve-as-fan-wrapper">
-       <label class="intro-approve-as-fan-label" for="intro-approve-as-fan-{{$intro_id}}">{{$as_fan}}</label>
-       <input type="radio" name="duplex" id="intro-approve-as-fan-{{$intro_id}}" class="intro-approve-as-fan" {{$fan_selected}} value="0"  />
-       <div class="intro-approve-fan-break"></div>
-</div>
-<div class="intro-approve-as-end"></div>
diff --git a/view/templates/notifications.tpl b/view/templates/notifications.tpl
deleted file mode 100644 (file)
index 9438db6..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-<h1>{{$notif_header}}</h1>
-
-{{if $tabs }}{{include file="common_tabs.tpl"}}{{/if}}
-
-<div class="notif-network-wrapper">
-       {{* The "show ignored" link *}}
-       {{if $notif_show_lnk}}<a href="{{$notif_show_lnk.href}}" id="notifications-show-hide-link">{{$notif_show_lnk.text}}</a>{{/if}}
-
-       {{* The notifications *}}
-       {{if $notif_content}}
-       {{foreach $notif_content as $notification}}
-               {{$notification nofilter}}
-       {{/foreach}}
-       {{/if}}
-
-       {{* If no notifications messages available *}}
-       {{if $notif_nocontent}}
-               <div class="notif_nocontent">{{$notif_nocontent}}</div>
-       {{/if}}
-
-       {{* The pager *}}
-       {{$notif_paginate nofilter}}
-</div>
diff --git a/view/templates/notifications/attend_item.tpl b/view/templates/notifications/attend_item.tpl
new file mode 100644 (file)
index 0000000..a8de3c7
--- /dev/null
@@ -0,0 +1,4 @@
+
+<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
+       <a href="{{$item_link}}"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
+</div>
\ No newline at end of file
diff --git a/view/templates/notifications/comments_item.tpl b/view/templates/notifications/comments_item.tpl
new file mode 100644 (file)
index 0000000..a8de3c7
--- /dev/null
@@ -0,0 +1,4 @@
+
+<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
+       <a href="{{$item_link}}"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
+</div>
\ No newline at end of file
diff --git a/view/templates/notifications/dislikes_item.tpl b/view/templates/notifications/dislikes_item.tpl
new file mode 100644 (file)
index 0000000..a8de3c7
--- /dev/null
@@ -0,0 +1,4 @@
+
+<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
+       <a href="{{$item_link}}"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
+</div>
\ No newline at end of file
diff --git a/view/templates/notifications/friends_item.tpl b/view/templates/notifications/friends_item.tpl
new file mode 100644 (file)
index 0000000..9df1554
--- /dev/null
@@ -0,0 +1,4 @@
+
+<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
+       <a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
+</div>
\ No newline at end of file
diff --git a/view/templates/notifications/intros.tpl b/view/templates/notifications/intros.tpl
new file mode 100644 (file)
index 0000000..808f155
--- /dev/null
@@ -0,0 +1,32 @@
+<h2>{{$header}}</h2>
+
+<div class="intro-wrapper" id="intro-{{$contact_id}}" >
+
+<p class="intro-desc">{{$str_notification_type}} {{$str_type}}</p>
+<img id="photo-{{$contact_id}}" class="intro-photo" src="{{$photo}}" width="175" height=175" title="{{$fullname}}" alt="{{$fullname}}" />
+<dl><dt>{{$lbl_url}}</dt><dd><a target="blank" href="{{$zrl}}">{{$url}}</a></dd></dl>
+{{if $location}}<dl><dt>{{$lbl_location}}</dt><dd>{{$location}}</dd></dl>{{/if}}
+{{if $gender}}<dl><dt>{{$lbl_gender}}</dt><dd>{{$gender}}</dd></dl>{{/if}}
+{{if $keywords}}<dl><dt>{{$lbl_keywords}}</dt><dd>{{$keywords}}</dd></dl>{{/if}}
+{{if $about}}<dl><dt>{{$lbl_about}}</dt><dd>{{$about nofilter}}</dd></dl>{{/if}}
+<div class="intro-knowyou">{{$lbl_knowyou}} {{$knowyou}}</div>
+<div class="intro-note" id="intro-note-{{$contact_id}}">{{$note}}</div>
+<div class="intro-wrapper-end" id="intro-wrapper-end-{{$contact_id}}"></div>
+<form class="intro-form" action="notifications/{{$intro_id}}" method="post">
+<input class="intro-submit-ignore" type="submit" name="submit" value="{{$ignore}}" />
+{{if $discard}}<input class="intro-submit-discard" type="submit" name="submit" value="{{$discard}}" />{{/if}}
+</form>
+<div class="intro-form-end"></div>
+
+<form class="intro-approve-form" action="{{$action}}" method="post">
+{{include file="field_checkbox.tpl" field=$hidden}}
+<input type="hidden" name="dfrn_id" value="{{$dfrn_id}}" >
+<input type="hidden" name="intro_id" value="{{$intro_id}}" >
+<input type="hidden" name="contact_id" value="{{$contact_id}}" >
+
+{{$dfrn_text nofilter}}
+
+<input class="intro-submit-approve" type="submit" name="submit" value="{{$approve}}" />
+</form>
+</div>
+<div class="intro-end"></div>
diff --git a/view/templates/notifications/likes_item.tpl b/view/templates/notifications/likes_item.tpl
new file mode 100644 (file)
index 0000000..a8de3c7
--- /dev/null
@@ -0,0 +1,4 @@
+
+<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
+       <a href="{{$item_link}}"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
+</div>
\ No newline at end of file
diff --git a/view/templates/notifications/netfriend.tpl b/view/templates/notifications/netfriend.tpl
new file mode 100644 (file)
index 0000000..465d7eb
--- /dev/null
@@ -0,0 +1,19 @@
+
+<div class="intro-approve-as-friend-desc">
+  <p>{{$approve_as1}}</p>
+  <p>{{$approve_as2}}</p>
+  <p>{{$approve_as3}}</p>
+</div>
+
+<div class="intro-approve-as-friend-wrapper">
+       <label class="intro-approve-as-friend-label" for="intro-approve-as-friend-{{$intro_id}}">{{$as_friend}}</label>
+       <input type="radio" name="duplex" id="intro-approve-as-friend-{{$intro_id}}" class="intro-approve-as-friend" {{$friend_selected}} value="1" />
+       <div class="intro-approve-friend-break" ></div> 
+</div>
+<div class="intro-approve-as-friend-end"></div>
+<div class="intro-approve-as-fan-wrapper">
+       <label class="intro-approve-as-fan-label" for="intro-approve-as-fan-{{$intro_id}}">{{$as_fan}}</label>
+       <input type="radio" name="duplex" id="intro-approve-as-fan-{{$intro_id}}" class="intro-approve-as-fan" {{$fan_selected}} value="0"  />
+       <div class="intro-approve-fan-break"></div>
+</div>
+<div class="intro-approve-as-end"></div>
diff --git a/view/templates/notifications/network_item.tpl b/view/templates/notifications/network_item.tpl
new file mode 100644 (file)
index 0000000..e2c0e24
--- /dev/null
@@ -0,0 +1,4 @@
+
+<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
+       <a href="{{$item_link}}"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
+</div>
diff --git a/view/templates/notifications/notification.tpl b/view/templates/notifications/notification.tpl
new file mode 100644 (file)
index 0000000..a8de3c7
--- /dev/null
@@ -0,0 +1,4 @@
+
+<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
+       <a href="{{$item_link}}"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
+</div>
\ No newline at end of file
diff --git a/view/templates/notifications/notifications.tpl b/view/templates/notifications/notifications.tpl
new file mode 100644 (file)
index 0000000..da3d15a
--- /dev/null
@@ -0,0 +1,25 @@
+
+
+<h1>{{$header}}</h1>
+
+{{if $tabs }}{{include file="common_tabs.tpl"}}{{/if}}
+
+<div class="notif-network-wrapper">
+       {{* The "show ignored" link *}}
+       {{if $showLink}}<a href="{{$showLink.href}}" id="notifications-show-hide-link">{{$showLink.text}}</a>{{/if}}
+
+       {{* The notifications *}}
+       {{if $notifications}}
+       {{foreach $notifications as $notification}}
+               {{$notification nofilter}}
+       {{/foreach}}
+       {{/if}}
+
+       {{* If no notifications messages available *}}
+       {{if $noContent}}
+               <div class="notification_nocontent">{{$noContent}}</div>
+       {{/if}}
+
+       {{* The pager *}}
+       {{$paginate nofilter}}
+</div>
diff --git a/view/templates/notifications/posts_item.tpl b/view/templates/notifications/posts_item.tpl
new file mode 100644 (file)
index 0000000..a8de3c7
--- /dev/null
@@ -0,0 +1,4 @@
+
+<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
+       <a href="{{$item_link}}"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
+</div>
\ No newline at end of file
diff --git a/view/templates/notifications/suggestions.tpl b/view/templates/notifications/suggestions.tpl
new file mode 100644 (file)
index 0000000..d7bb7b6
--- /dev/null
@@ -0,0 +1,22 @@
+
+
+<div class="intro-wrapper" >
+
+<p class="intro-desc">{{$str_notification_type}} {{$str_type}}</p>
+{{if $madeby}}<div class="intro-madeby">{{$lbl_madeby}} {{$madeby}}</div>{{/if}}
+<div class="intro-fullname" >{{$fullname}}</div>
+<a class="intro-url-link" href="{{$url}}" ><img class="intro-photo lframe" src="{{$photo}}" width="175" height="175" title="{{$fullname}}" alt="{{$fullname}}" /></a>
+<div class="intro-note" >{{$note}}</div>
+<div class="intro-wrapper-end"></div>
+<form class="intro-form" action="notifications/{{$intro_id}}" method="post">
+<input class="intro-submit-ignore" type="submit" name="submit" value="{{$ignore}}" />
+<input class="intro-submit-discard" type="submit" name="submit" value="{{$discard}}" />
+</form>
+<div class="intro-form-end"></div>
+
+<form class="intro-approve-form" action="{{$request}}" method="get">
+{{include file="field_checkbox.tpl" field=$hidden}}
+<input class="intro-submit-approve" type="submit" name="submit" value="{{$approve}}" />
+</form>
+</div>
+<div class="intro-end"></div>
diff --git a/view/templates/notifications_attend_item.tpl b/view/templates/notifications_attend_item.tpl
deleted file mode 100644 (file)
index 6fb69ed..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-
-<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
-       <a href="{{$item_link}}" target="friendica-notification"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
-</div>
\ No newline at end of file
diff --git a/view/templates/notifications_comments_item.tpl b/view/templates/notifications_comments_item.tpl
deleted file mode 100644 (file)
index 9df1554..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-
-<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
-       <a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
-</div>
\ No newline at end of file
diff --git a/view/templates/notifications_dislikes_item.tpl b/view/templates/notifications_dislikes_item.tpl
deleted file mode 100644 (file)
index 9df1554..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-
-<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
-       <a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
-</div>
\ No newline at end of file
diff --git a/view/templates/notifications_friends_item.tpl b/view/templates/notifications_friends_item.tpl
deleted file mode 100644 (file)
index 9df1554..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-
-<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
-       <a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
-</div>
\ No newline at end of file
diff --git a/view/templates/notifications_likes_item.tpl b/view/templates/notifications_likes_item.tpl
deleted file mode 100644 (file)
index 6fb69ed..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-
-<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
-       <a href="{{$item_link}}" target="friendica-notification"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
-</div>
\ No newline at end of file
diff --git a/view/templates/notifications_network_item.tpl b/view/templates/notifications_network_item.tpl
deleted file mode 100644 (file)
index 0373b0d..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-
-<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
-       <a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
-</div>
diff --git a/view/templates/notifications_posts_item.tpl b/view/templates/notifications_posts_item.tpl
deleted file mode 100644 (file)
index 9df1554..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-
-<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
-       <a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
-</div>
\ No newline at end of file
diff --git a/view/templates/notify.tpl b/view/templates/notify.tpl
deleted file mode 100644 (file)
index 9df1554..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-
-<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
-       <a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text nofilter}} <span class="notif-when">{{$item_ago}}</span></a>
-</div>
\ No newline at end of file
diff --git a/view/templates/profed_head.tpl b/view/templates/profed_head.tpl
deleted file mode 100644 (file)
index f7e1fb1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<script type="text/javascript" src="view/js/country.js" ></script>
\ No newline at end of file
diff --git a/view/templates/profile-hide-friends.tpl b/view/templates/profile-hide-friends.tpl
deleted file mode 100644 (file)
index 80e6dcb..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<div id="profile-edit-hide-friends-wrapper">
-       {{include file="field_yesno.tpl" field=$yesno}}
-</div>
diff --git a/view/templates/profile-hide-wall.tpl b/view/templates/profile-hide-wall.tpl
deleted file mode 100644 (file)
index ff106fa..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-
-<p id="hide-wall-text">
-{{$desc nofilter}}
-</p>
-
-               <div id="hide-wall-yes-wrapper">
-               <label id="hide-wall-yes-label" for="hide-wall-yes">{{$yes_str}}</label>
-               <input type="radio" name="hidewall" id="hide-wall-yes" {{$yes_selected}} value="1" />
-
-               <div id="hide-wall-break" ></div>       
-               </div>
-               <div id="hide-wall-no-wrapper">
-               <label id="hide-wall-no-label" for="hide-wall-no">{{$no_str}}</label>
-               <input type="radio" name="hidewall" id="hide-wall-no" {{$no_selected}} value="0"  />
-
-               <div id="hide-wall-end"></div>
-               </div>
diff --git a/view/templates/profile-in-directory.tpl b/view/templates/profile-in-directory.tpl
deleted file mode 100644 (file)
index bfc13e8..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-
-<p id="profile-in-directory">
-{{$desc nofilter}}
-</p>
-
-               <div id="profile-in-dir-yes-wrapper">
-               <label id="profile-in-dir-yes-label" for="profile-in-dir-yes">{{$yes_str}}</label>
-               <input type="radio" name="profile_in_directory" id="profile-in-dir-yes" {{$yes_selected}} value="1" />
-
-               <div id="profile-in-dir-break" ></div>  
-               </div>
-               <div id="profile-in-dir-no-wrapper">
-               <label id="profile-in-dir-no-label" for="profile-in-dir-no">{{$no_str}}</label>
-               <input type="radio" name="profile_in_directory" id="profile-in-dir-no" {{$no_selected}} value="0"  />
-
-               <div id="profile-in-dir-end"></div>
-               </div>
diff --git a/view/templates/profile-in-netdir.tpl b/view/templates/profile-in-netdir.tpl
deleted file mode 100644 (file)
index c91601b..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-
-<p id="profile-in-directory">
-{{$desc nofilter}}
-</p>
-
-               <div id="profile-in-netdir-yes-wrapper">
-               <label id="profile-in-netdir-yes-label" for="profile-in-netdir-yes">{{$yes_str}}</label>
-               <input type="radio" name="profile_in_netdirectory" id="profile-in-netdir-yes" {{$yes_selected}} value="1" />
-
-               <div id="profile-in-netdir-break" ></div>       
-               </div>
-               <div id="profile-in-netdir-no-wrapper">
-               <label id="profile-in-netdir-no-label" for="profile-in-netdir-no">{{$no_str}}</label>
-               <input type="radio" name="profile_in_netdirectory" id="profile-in-netdir-no" {{$no_selected}} value="0"  />
-
-               <div id="profile-in-netdir-end"></div>
-               </div>
diff --git a/view/templates/profile/advanced.tpl b/view/templates/profile/advanced.tpl
deleted file mode 100644 (file)
index 44e763f..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-
-{{include file="section_title.tpl"}}
-
-<dl id="aprofile-fullname" class="aprofile">
- <dt>{{$profile.fullname.0}}</dt>
- <dd>{{$profile.fullname.1}}</dd>
-</dl>
-
-{{if $profile.membersince}}
-<dl id="aprofile-membersince" class="aprofile">
- <dt>{{$profile.membersince.0}}</dt>
- <dd>{{$profile.membersince.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.gender}}
-<dl id="aprofile-gender" class="aprofile">
- <dt>{{$profile.gender.0}}</dt>
- <dd>{{$profile.gender.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.birthday}}
-<dl id="aprofile-birthday" class="aprofile">
- <dt>{{$profile.birthday.0}}</dt>
- <dd>{{$profile.birthday.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.age}}
-<dl id="aprofile-age" class="aprofile">
- <dt>{{$profile.age.0}}</dt>
- <dd>{{$profile.age.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.marital}}
-<dl id="aprofile-marital" class="aprofile">
- <dt><span class="heart">&hearts;</span>  {{$profile.marital.0}}</dt>
- <dd>{{$profile.marital.1}}{{if $profile.marital.with}} ({{$profile.marital.with nofilter}}){{/if}}{{if $profile.howlong}} {{$profile.howlong}}{{/if}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.sexual}}
-<dl id="aprofile-sexual" class="aprofile">
- <dt>{{$profile.sexual.0}}</dt>
- <dd>{{$profile.sexual.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.pub_keywords}}
-<dl id="aprofile-tags" class="aprofile">
- <dt>{{$profile.pub_keywords.0}}</dt>
- <dd>{{$profile.pub_keywords.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.homepage}}
-<dl id="aprofile-homepage" class="aprofile">
- <dt>{{$profile.homepage.0}}</dt>
- <dd>{{$profile.homepage.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.hometown}}
-<dl id="aprofile-hometown" class="aprofile">
- <dt>{{$profile.hometown.0}}</dt>
- <dd>{{$profile.hometown.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.politic}}
-<dl id="aprofile-politic" class="aprofile">
- <dt>{{$profile.politic.0}}</dt>
- <dd>{{$profile.politic.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.religion}}
-<dl id="aprofile-religion" class="aprofile">
- <dt>{{$profile.religion.0}}</dt>
- <dd>{{$profile.religion.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.about}}
-<dl id="aprofile-about" class="aprofile">
- <dt>{{$profile.about.0}}</dt>
- <dd>{{$profile.about.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.interest}}
-<dl id="aprofile-interest" class="aprofile">
- <dt>{{$profile.interest.0}}</dt>
- <dd>{{$profile.interest.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.likes}}
-<dl id="aprofile-likes" class="aprofile">
- <dt>{{$profile.likes.0}}</dt>
- <dd>{{$profile.likes.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.dislikes}}
-<dl id="aprofile-dislikes" class="aprofile">
- <dt>{{$profile.dislikes.0}}</dt>
- <dd>{{$profile.dislikes.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.contact}}
-<dl id="aprofile-contact" class="aprofile">
- <dt>{{$profile.contact.0}}</dt>
- <dd>{{$profile.contact.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
-{{if $profile.music}}
-<dl id="aprofile-music" class="aprofile">
- <dt>{{$profile.music.0}}</dt>
- <dd>{{$profile.music.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
-{{if $profile.book}}
-<dl id="aprofile-book" class="aprofile">
- <dt>{{$profile.book.0}}</dt>
- <dd>{{$profile.book.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
-{{if $profile.tv}}
-<dl id="aprofile-tv" class="aprofile">
- <dt>{{$profile.tv.0}}</dt>
- <dd>{{$profile.tv.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
-{{if $profile.film}}
-<dl id="aprofile-film" class="aprofile">
- <dt>{{$profile.film.0}}</dt>
- <dd>{{$profile.film.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
-{{if $profile.romance}}
-<dl id="aprofile-romance" class="aprofile">
- <dt>{{$profile.romance.0}}</dt>
- <dd>{{$profile.romance.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
-{{if $profile.work}}
-<dl id="aprofile-work" class="aprofile">
- <dt>{{$profile.work.0}}</dt>
- <dd>{{$profile.work.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.education}}
-<dl id="aprofile-education" class="aprofile">
- <dt>{{$profile.education.0}}</dt>
- <dd>{{$profile.education.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
-{{if $profile.forumlist}}
-<dl id="aprofile-forumlist" class="aprofile">
- <dt>{{$profile.forumlist.0}}</dt>
- <dd>{{$profile.forumlist.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
diff --git a/view/templates/profile/index.tpl b/view/templates/profile/index.tpl
new file mode 100644 (file)
index 0000000..60bf46b
--- /dev/null
@@ -0,0 +1,103 @@
+<div id="profile-page" class="generic-page-wrapper">
+    {{include file="section_title.tpl"}}
+
+    {{* The link to edit the profile*}}
+{{if $is_owner}}
+       <div id="profile-edit-links">
+               <ul class="nav nav-pills preferences">
+                       <li class="pull-right">
+                               <a class="btn btn-link btn-sm" type="button" id="profile-edit-link" href="{{$edit_link.url}}" title="{{$edit_link.title}}">
+                                       <i class="fa fa-pencil-square-o" aria-hidden="true"></i>&nbsp;{{$edit_link.label}}
+                               </a>
+                       </li>
+               {{if count($view_as_contacts)}}
+                       <li class="pull-right">
+                               <form action="{{$query_string}}" method="get">
+                                       <button type="submit" class="btn btn-sm">{{$view_as}}</button>
+                                       <select name="viewas" class="input-sm">
+                                               <option value="0">Yourself</option>
+                               {{foreach $view_as_contacts as $contact}}
+                                               <option value="{{$contact.id}}"{{if $contact.id == $view_as_contact_id}} selected{{/if}}>{{$contact.name}}</option>
+                               {{/foreach}}
+                                       </select>
+
+                               </form>
+                       </li>
+               {{/if}}
+               </ul>
+               <div class="clear"></div>
+       </div>
+{{/if}}
+       <dl id="{{$basic_fields.fullname.id}}" class="row {{$basic_fields.fullname.class|default:'aprofile'}}">
+               <dt class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$basic_fields.fullname.label}}</dt>
+               <dd class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$basic_fields.fullname.value}}</dd>
+       </dl>
+
+{{if $basic_fields.membersince}}
+       <dl id="aprofile-membersince" class="row {{$basic_fields.membersince.class|default:'aprofile'}}">
+               <hr class="profile-separator">
+               <dt class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$basic_fields.membersince.label}}</dt>
+               <dd class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$basic_fields.membersince.value}}</dd>
+       </dl>
+{{/if}}
+
+{{if $basic_fields.birthday}}
+       <dl id="aprofile-birthday" class="row {{$basic_fields.birthday.class|default:'aprofile'}}">
+               <hr class="profile-separator">
+               <dt class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$basic_fields.birthday.label}}</dt>
+               <dd class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$basic_fields.birthday.value}}</dd>
+       </dl>
+{{/if}}
+
+{{if $basic_fields.age}}
+       <dl id="aprofile-age" class="row {{$basic_fields.age.class|default:'aprofile'}}">
+               <hr class="profile-separator">
+               <dt class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$basic_fields.age.label}}</dt>
+               <dd class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$basic_fields.age.value}}</dd>
+       </dl>
+{{/if}}
+
+{{if $basic_fields.location}}
+       <dl id="aprofile-location" class="row {{$basic_fields.location.class|default:'aprofile'}}">
+               <hr class="profile-separator">
+               <dt class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$basic_fields.location.label}}</dt>
+               <dd class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$basic_fields.location.value}}</dd>
+       </dl>
+{{/if}}
+
+{{if $basic_fields.homepage}}
+       <dl id="aprofile-homepage" class="row {{$basic_fields.homepage.class|default:'aprofile'}}">
+               <hr class="profile-separator">
+               <dt class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$basic_fields.homepage.label}}</dt>
+               <dd class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$basic_fields.homepage.value nofilter}}</dd>
+       </dl>
+{{/if}}
+
+{{if $basic_fields.xmpp}}
+       <dl id="aprofile-xmpp" class="row {{$basic_fields.xmpp.class|default:'aprofile'}}">
+               <hr class="profile-separator">
+               <dt class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$basic_fields.xmpp.label}}</dt>
+               <dd class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$basic_fields.xmpp.value nofilter}}</dd>
+       </dl>
+{{/if}}
+
+{{if $basic_fields.pub_keywords}}
+       <dl id="aprofile-tags" class="row {{$basic_fields.pub_keywords.class|default:'aprofile'}}">
+               <hr class="profile-separator">
+               <dt class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$basic_fields.pub_keywords.label}}</dt>
+               <dd class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">
+            {{foreach $basic_fields.pub_keywords.value as $tag}}
+                               <a href="{{$tag.url}}" class="tag label btn-info sm">{{$tag.label}} <i class="fa fa-bolt" aria-hidden="true"></i></a>
+            {{/foreach}}
+               </dd>
+       </dl>
+{{/if}}
+
+{{foreach $custom_fields as $custom_field}}
+       <dl id="{{$custom_field.id}}" class="row {{$custom_field.class|default:'aprofile'}}">
+               <hr class="profile-separator">
+               <dt class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$custom_field.label}}</dt>
+               <dd class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$custom_field.value nofilter}}</dd>
+       </dl>
+{{/foreach}}
+</div>
diff --git a/view/templates/profile_edit.tpl b/view/templates/profile_edit.tpl
deleted file mode 100644 (file)
index 08e833f..0000000
+++ /dev/null
@@ -1,458 +0,0 @@
-
-{{$default nofilter}}
-
-<h1>{{$banner}}</h1>
-
-<div id="profile-edit-links">
-<ul>
-<li><a href="profile_photo" id="profile-photo_upload-link" title="{{$profpic}}">{{$profpic}}</a></li>
-<li><a href="profile/{{$profile_id}}/view?tab=profile" id="profile-edit-view-link" title="{{$viewprof}}">{{$viewprof}}</a></li>
-<li><a href="{{$profile_clone_link}}" id="profile-edit-clone-link" title="{{$cr_prof}}">{{$cl_prof}}</a></li>
-<li></li>
-<li><a href="{{$profile_drop_link}}" id="profile-edit-drop-link" title="{{$del_prof}}" {{$disabled}} >{{$del_prof}}</a></li>
-
-</ul>
-</div>
-
-<div id="profile-edit-links-end"></div>
-
-
-<div id="profile-edit-wrapper" >
-<form id="profile-edit-form" name="form1" action="profiles/{{$profile_id}}" method="post" >
-<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
-
-{{if $detailled_profile}}
-{{include file="field_yesno.tpl" field=$details}}
-<div id="profile-edit-profile-name-wrapper" >
-<label id="profile-edit-profile-name-label" for="profile-edit-profile-name" >{{$profile_name.1}} </label>
-<input type="text" size="32" name="profile_name" id="profile-edit-profile-name" value="{{$profile_name.2}}" /><div class="required">*</div>
-</div>
-<div id="profile-edit-profile-name-end"></div>
-
-<div id="profile-edit-name-wrapper" >
-<label id="profile-edit-name-label" for="profile-edit-name" >{{$name.1}} </label>
-<input type="text" size="32" name="name" id="profile-edit-name" value="{{$name.2}}" />
-</div>
-<div id="profile-edit-name-end"></div>
-
-<div id="profile-edit-pdesc-wrapper" >
-<label id="profile-edit-pdesc-label" for="profile-edit-pdesc" >{{$pdesc.1}} </label>
-<input type="text" size="32" name="pdesc" id="profile-edit-pdesc" value="{{$pdesc.1}}" />
-</div>
-<div id="profile-edit-pdesc-end"></div>
-
-
-<div id="profile-edit-gender-wrapper" >
-<label id="profile-edit-gender-label" for="gender-select" >{{$lbl_gender}} </label>
-{{$gender nofilter}}
-</div>
-<div id="profile-edit-gender-end"></div>
-
-<div id="profile-edit-dob-wrapper" >
-{{$dob nofilter}}
-</div>
-<div id="profile-edit-dob-end"></div>
-
-{{$hide_friends nofilter}}
-
-<div class="profile-edit-submit-wrapper" >
-<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}" />
-</div>
-<div class="profile-edit-submit-end"></div>
-
-
-<div id="profile-edit-address-wrapper" >
-<label id="profile-edit-address-label" for="profile-edit-address" >{{$address.1}} </label>
-<input type="text" size="32" name="address" id="profile-edit-address" value="{{$address.2}}" />
-</div>
-<div id="profile-edit-address-end"></div>
-
-<div id="profile-edit-locality-wrapper" >
-<label id="profile-edit-locality-label" for="profile-edit-locality" >{{$locality.1}} </label>
-<input type="text" size="32" name="locality" id="profile-edit-locality" value="{{$locality.2}}" />
-</div>
-<div id="profile-edit-locality-end"></div>
-
-
-<div id="profile-edit-postal-code-wrapper" >
-<label id="profile-edit-postal-code-label" for="profile-edit-postal-code" >{{$postal_code.1}} </label>
-<input type="text" size="32" name="postal_code" id="profile-edit-postal-code" value="{{$postal_code.2}}" />
-</div>
-<div id="profile-edit-postal-code-end"></div>
-
-<div id="profile-edit-country-name-wrapper" >
-<label id="profile-edit-country-name-label" for="profile-edit-country-name" >{{$country_name.1}} </label>
-<select name="country_name" id="profile-edit-country-name" onChange="Fill_States('{{$region.2}}');">
-<option selected="selected" >{{$country_name.2}}</option>
-<option>temp</option>
-</select>
-</div>
-<div id="profile-edit-country-name-end"></div>
-
-<div id="profile-edit-region-wrapper" >
-<label id="profile-edit-region-label" for="profile-edit-region" >{{$region.1}} </label>
-<select name="region" id="profile-edit-region" onChange="Update_Globals();" >
-<option selected="selected" >{{$region.2}}</option>
-<option>temp</option>
-</select>
-</div>
-<div id="profile-edit-region-end"></div>
-
-<div id="profile-edit-hometown-wrapper" >
-<label id="profile-edit-hometown-label" for="profile-edit-hometown" >{{$hometown.1}} </label>
-<input type="text" size="32" name="hometown" id="profile-edit-hometown" value="{{$hometown.2}}" />
-</div>
-<div id="profile-edit-hometown-end"></div>
-
-<div class="profile-edit-submit-wrapper" >
-<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}" />
-</div>
-<div class="profile-edit-submit-end"></div>
-
-<div id="profile-edit-marital-wrapper" >
-<label id="profile-edit-marital-label" for="profile-edit-marital" >{{$lbl_marital nofilter}} </label>
-{{$marital nofilter}}
-</div>
-<label id="profile-edit-with-label" for="profile-edit-with" > {{$with.1}} </label>
-<input type="text" size="32" name="with" id="profile-edit-with" title="{{$with.3}}" value="{{$with.2}}" />
-<label id="profile-edit-howlong-label" for="profile-edit-howlong" > {{$howlong.1}} </label>
-<input type="text" size="32" name="howlong" id="profile-edit-howlong" title="{{$howlong.1}}" value="{{$howlong.1}}" />
-
-<div id="profile-edit-marital-end"></div>
-
-<div id="profile-edit-sexual-wrapper" >
-<label id="profile-edit-sexual-label" for="sexual-select" >{{$lbl_sexual}} </label>
-{{$sexual nofilter}}
-</div>
-<div id="profile-edit-sexual-end"></div>
-
-
-
-<div id="profile-edit-homepage-wrapper" >
-<label id="profile-edit-homepage-label" for="profile-edit-homepage" >{{$homepage.1}} </label>
-<input type="url" size="32" name="homepage" id="profile-edit-homepage" value="{{$homepage.2}}" />
-</div>
-<div id="profile-edit-homepage-end"></div>
-
-<div id="profile-edit-xmpp-wrapper" >
-<label id="profile-edit-xmpp-label" for="profile-edit-xmpp" >{{$xmpp.1}} </label>
-<input type="text" size="32" name="xmpp" id="profile-edit-xmpp" title="{{$lbl_ex2}}" value="{{$xmpp.2}}" />
-</div><div id="profile-edit-xmpp-desc">{{$xmpp.3}}</div>
-<div id="profile-edit-xmpp-end"></div>
-
-
-<div id="profile-edit-politic-wrapper" >
-<label id="profile-edit-politic-label" for="profile-edit-politic" >{{$politic.1}} </label>
-<input type="text" size="32" name="politic" id="profile-edit-politic" value="{{$politic.2}}" />
-</div>
-<div id="profile-edit-politic-end"></div>
-
-<div id="profile-edit-religion-wrapper" >
-<label id="profile-edit-religion-label" for="profile-edit-religion" >{{$religion.1}} </label>
-<input type="text" size="32" name="religion" id="profile-edit-religion" value="{{$religion.2}}" />
-</div>
-<div id="profile-edit-religion-end"></div>
-
-<div id="profile-edit-pubkeywords-wrapper" >
-<label id="profile-edit-pubkeywords-label" for="profile-edit-pubkeywords" >{{$pub_keywords.1}} </label>
-<input type="text" size="32" name="pub_keywords" id="profile-edit-pubkeywords" title="{{$lbl_ex2}}" value="{{$pub_keywords.2}}" />
-</div><div id="profile-edit-pubkeywords-desc">{{$pub_keywords.3}}</div>
-<div id="profile-edit-pubkeywords-end"></div>
-
-<div id="profile-edit-prvkeywords-wrapper" >
-<label id="profile-edit-prvkeywords-label" for="profile-edit-prvkeywords" >{{$prv_keywords.1}} </label>
-<input type="text" size="32" name="prv_keywords" id="profile-edit-prvkeywords" title="{{$lbl_ex2}}" value="{{$prv_keywords.2}}" />
-</div><div id="profile-edit-prvkeywords-desc">{{$prv_keywords.3}}</div>
-<div id="profile-edit-prvkeywords-end"></div>
-
-
-<div class="profile-edit-submit-wrapper" >
-<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}" />
-</div>
-<div class="profile-edit-submit-end"></div>
-
-<div id="about-jot-wrapper" >
-<p id="about-jot-desc" >
-{{$about.1}}
-</p>
-
-<textarea rows="10" cols="72" id="profile-about-text" name="about" >{{$about.2}}</textarea>
-
-</div>
-<div id="about-jot-end"></div>
-
-
-<div id="interest-jot-wrapper" >
-<p id="interest-jot-desc" >
-{{$interest.1}}
-</p>
-
-<textarea rows="10" cols="72" id="interest-jot-text" name="interest" >{{$interest.2}}</textarea>
-
-</div>
-<div id="interest-jot-end"></div>
-
-
-<div id="likes-jot-wrapper" >
-<p id="likes-jot-desc" >
-{{$likes.1}}
-</p>
-
-<textarea rows="10" cols="72" id="likes-jot-text" name="likes" >{{$likes.2}}</textarea>
-
-</div>
-<div id="likes-jot-end"></div>
-
-
-<div id="dislikes-jot-wrapper" >
-<p id="dislikes-jot-desc" >
-{{$dislikes.1}}
-</p>
-
-<textarea rows="10" cols="72" id="dislikes-jot-text" name="dislikes" >{{$dislikes.2}}</textarea>
-
-</div>
-<div id="dislikes-jot-end"></div>
-
-
-<div id="contact-jot-wrapper" >
-<p id="contact-jot-desc" >
-{{$contact.1}}
-</p>
-
-<textarea rows="10" cols="72" id="contact-jot-text" name="contact" >{{$contact.2}}</textarea>
-
-</div>
-<div id="contact-jot-end"></div>
-
-
-<div class="profile-edit-submit-wrapper" >
-<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}" />
-</div>
-<div class="profile-edit-submit-end"></div>
-
-
-<div id="music-jot-wrapper" >
-<p id="music-jot-desc" >
-{{$music.1}}
-</p>
-
-<textarea rows="10" cols="72" id="music-jot-text" name="music" >{{$music.2}}</textarea>
-
-</div>
-<div id="music-jot-end"></div>
-
-<div id="book-jot-wrapper" >
-<p id="book-jot-desc" >
-{{$book.1}}
-</p>
-
-<textarea rows="10" cols="72" id="book-jot-text" name="book" >{{$book.2}}</textarea>
-
-</div>
-<div id="book-jot-end"></div>
-
-
-
-<div id="tv-jot-wrapper" >
-<p id="tv-jot-desc" >
-{{$tv.1}} 
-</p>
-
-<textarea rows="10" cols="72" id="tv-jot-text" name="tv" >{{$tv.2}}</textarea>
-
-</div>
-<div id="tv-jot-end"></div>
-
-
-
-<div id="film-jot-wrapper" >
-<p id="film-jot-desc" >
-{{$film.1}}
-</p>
-
-<textarea rows="10" cols="72" id="film-jot-text" name="film" >{{$film.2}}</textarea>
-
-</div>
-<div id="film-jot-end"></div>
-
-
-<div class="profile-edit-submit-wrapper" >
-<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}" />
-</div>
-<div class="profile-edit-submit-end"></div>
-
-
-<div id="romance-jot-wrapper" >
-<p id="romance-jot-desc" >
-{{$romance.1}}
-</p>
-
-<textarea rows="10" cols="72" id="romance-jot-text" name="romance" >{{$romance.2}}</textarea>
-
-</div>
-<div id="romance-jot-end"></div>
-
-
-
-<div id="work-jot-wrapper" >
-<p id="work-jot-desc" >
-{{$work.1}}
-</p>
-
-<textarea rows="10" cols="72" id="work-jot-text" name="work" >{{$work.2}}</textarea>
-
-</div>
-<div id="work-jot-end"></div>
-
-
-
-<div id="education-jot-wrapper" >
-<p id="education-jot-desc" >
-{{$education.1}} 
-</p>
-
-<textarea rows="10" cols="72" id="education-jot-text" name="education" >{{$education.2}}</textarea>
-
-</div>
-<div id="education-jot-end"></div>
-
-
-
-<div class="profile-edit-submit-wrapper" >
-<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}" />
-</div>
-<div class="profile-edit-submit-end"></div>
-
-{{else}}
-{{if $personal_account}}
-{{include file="field_yesno.tpl" field=$details}}
-{{/if}}
-<div id="profile-edit-profile-name-wrapper" >
-<label id="profile-edit-profile-name-label" for="profile-edit-profile-name" >{{$profile_name.1}} </label>
-<input type="text" size="32" name="profile_name" id="profile-edit-profile-name" value="{{$profile_name.2}}" /><div class="required">*</div>
-</div>
-<div id="profile-edit-profile-name-end"></div>
-
-<div id="profile-edit-name-wrapper" >
-<label id="profile-edit-name-label" for="profile-edit-name" >{{$name.1}} </label>
-<input type="text" size="32" name="name" id="profile-edit-name" value="{{$name.2}}" />
-</div>
-<div id="profile-edit-name-end"></div>
-
-{{if $personal_account}}
-<div id="profile-edit-gender-wrapper" >
-<label id="profile-edit-gender-label" for="gender-select" >{{$lbl_gender}} </label>
-{{$gender nofilter}}
-</div>
-<div id="profile-edit-gender-end"></div>
-
-<div id="profile-edit-dob-wrapper" >
-{{$dob nofilter}}
-</div>
-<div id="profile-edit-dob-end"></div>
-{{/if}}
-
-<div id="profile-edit-homepage-wrapper" >
-<label id="profile-edit-homepage-label" for="profile-edit-homepage" >{{$homepage.1}} </label>
-<input type="url" size="32" name="homepage" id="profile-edit-homepage" value="{{$homepage.2}}" />
-</div>
-<div id="profile-edit-homepage-end"></div>
-
-<div id="profile-edit-xmpp-wrapper" >
-<label id="profile-edit-xmpp-label" for="profile-edit-xmpp" >{{$xmpp.1}} </label>
-<input type="text" size="32" name="xmpp" id="profile-edit-xmpp" title="{{$lbl_ex2}}" value="{{$xmpp.2}}" />
-</div><div id="profile-edit-xmpp-desc">{{$xmpp.3}}</div>
-<div id="profile-edit-xmpp-end"></div>
-
-
-{{$hide_friends nofilter}}
-
-<div id="profile-edit-address-wrapper" >
-<label id="profile-edit-address-label" for="profile-edit-address" >{{$address.1}} </label>
-<input type="text" size="32" name="address" id="profile-edit-address" value="{{$address.2}}" />
-</div>
-<div id="profile-edit-address-end"></div>
-
-<div id="profile-edit-locality-wrapper" >
-<label id="profile-edit-locality-label" for="profile-edit-locality" >{{$locality.1}} </label>
-<input type="text" size="32" name="locality" id="profile-edit-locality" value="{{$locality.2}}" />
-</div>
-<div id="profile-edit-locality-end"></div>
-
-
-<div id="profile-edit-postal-code-wrapper" >
-<label id="profile-edit-postal-code-label" for="profile-edit-postal-code" >{{$postal_code.1}} </label>
-<input type="text" size="32" name="postal_code" id="profile-edit-postal-code" value="{{$postal_code.2}}" />
-</div>
-<div id="profile-edit-postal-code-end"></div>
-
-<div id="profile-edit-country-name-wrapper" >
-<label id="profile-edit-country-name-label" for="profile-edit-country-name" >{{$country_name.1}} </label>
-<select name="country_name" id="profile-edit-country-name" onChange="Fill_States('{{$region.2}}');">
-<option selected="selected" >{{$country_name.1}}</option>
-<option>temp</option>
-</select>
-</div>
-<div id="profile-edit-country-name-end"></div>
-
-<div id="profile-edit-region-wrapper" >
-<label id="profile-edit-region-label" for="profile-edit-region" >{{$region.1}} </label>
-<select name="region" id="profile-edit-region" onChange="Update_Globals();" >
-<option selected="selected" >{{$region.2}}</option>
-<option>temp</option>
-</select>
-</div>
-<div id="profile-edit-region-end"></div>
-
-<div id="profile-edit-pubkeywords-wrapper" >
-<label id="profile-edit-pubkeywords-label" for="profile-edit-pubkeywords" >{{$pub_keywords.1}} </label>
-<input type="text" size="32" name="pub_keywords" id="profile-edit-pubkeywords" title="{{$lbl_ex2}}" value="{{$pub_keywords.2}}" />
-</div><div id="profile-edit-pubkeywords-desc">{{$pub_keywords.3}}</div>
-<div id="profile-edit-pubkeywords-end"></div>
-
-<div id="profile-edit-prvkeywords-wrapper" >
-<label id="profile-edit-prvkeywords-label" for="profile-edit-prvkeywords" >{{$prv_keywords.1}} </label>
-<input type="text" size="32" name="prv_keywords" id="profile-edit-prvkeywords" title="{{$lbl_ex2}}" value="{{$prv_keywords.2}}" />
-</div><div id="profile-edit-prvkeywords-desc">{{$prv_keywords.3}}</div>
-<div id="profile-edit-prvkeywords-end"></div>
-
-<div id="about-jot-wrapper" >
-<p id="about-jot-desc" >
-{{$about.1}}
-</p>
-
-<textarea rows="10" cols="72" id="profile-about-text" name="about" >{{$about.2}}</textarea>
-
-</div>
-<div id="about-jot-end"></div>
-
-<div class="profile-edit-submit-wrapper" >
-<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}" />
-</div>
-<div class="profile-edit-submit-end"></div>
-
-        <input type="hidden" name="pdesc" id="profile-edit-pdesc" value="{{$pdesc.2}}" />
-        <input type="hidden" id="contact-jot-text" name="contact" value="{{$contact.2}}" />
-        <input type="hidden" name="hometown" id="profile-edit-hometown" value="{{$hometown.2}}" />
-        <input type="hidden" name="politic" id="profile-edit-politic" value="{{$politic.2}}" />
-        <input type="hidden" name="religion" id="profile-edit-religion" value="{{$religion.2}}" />
-        <input type="hidden" id="likes-jot-text" name="likes" value="{{$likes.2}}" />
-        <input type="hidden" id="dislikes-jot-text" name="dislikes" value="{{$dislikes.2}}" />
-        <input type="hidden" name="marital" id="profile-edit-marital" value="{{$marital.2}}" />
-        <input type="hidden" name="with" id="profile-edit-with" value="{{$with.2}}" />
-        <input type="hidden" name="howlong" id="profile-edit-howlong" value="{{$howlong.2}}" />
-        <input type="hidden" name="sexual" id="profile-edit-sexual" value="{{$sexual.2}}" />
-        <input type="hidden" id="romance-jot-text" name="romance" value="{{$romance.2}}" />
-        <input type="hidden" id="work-jot-text" name="work" value="{{$work.2}}" />
-        <input type="hidden" id="education-jot-text" name="education" value="{{$education.2}}" />
-        <input type="hidden" id="interest-jot-text" name="interest" value="{{$interest.2}}" />
-        <input type="hidden" id="music-jot-text" name="music" value="{{$music.2}}" />
-        <input type="hidden" id="book-jot-text" name="book" value="{{$book.2}}" />
-        <input type="hidden" id="tv-jot-text" name="tv" value="{{$tv.2}}" />
-        <input type="hidden" id="film-jot-text" name="film" value="{{$film.2}}" />
-
-{{/if}}
-</form>
-</div>
-<script type="text/javascript">Fill_Country('{{$country_name.2}}');Fill_States('{{$region.2}}');</script>
diff --git a/view/templates/profile_edlink.tpl b/view/templates/profile_edlink.tpl
deleted file mode 100644 (file)
index 54d7a34..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-
-<div class="profile-edit-side-div"><a class="profile-edit-side-link icon edit" title="{{$editprofile}}" href="profiles/{{$profid}}" ></a></div>
-<div class="clear"></div>
\ No newline at end of file
diff --git a/view/templates/profile_entry.tpl b/view/templates/profile_entry.tpl
deleted file mode 100644 (file)
index e7c3a31..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-
-<div class="profile-listing" >
-       <div class="profile-listing-photo-wrapper" >
-               <a href="profiles/{{$id}}" class="profile-listing-edit-link"><img class="profile-listing-photo" id="profile-listing-photo-{{$id}}" src="{{$photo}}" alt="{{$alt}}" /></a>
-       </div>
-       <div class="profile-listing-photo-end"></div>
-       <div class="profile-listing-name" id="profile-listing-name-{{$id}}">
-               <a href="profiles/{{$id}}" class="profile-listing-edit-link" >{{$profile_name}}</a>
-       </div>
-       <div class="profile-listing-visible">{{$visible nofilter}}</div>
-</div>
-<div class="profile-listing-end"></div>
diff --git a/view/templates/profile_listing_header.tpl b/view/templates/profile_listing_header.tpl
deleted file mode 100644 (file)
index 65f38f3..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-
-<h1>{{$header}}</h1>
-
-<p id="profile-listing-desc" class="button" >
-       <a href="profile_photo" >{{$chg_photo}}</a>
-</p>
-
-<div id="profile-listing-new-link-wrapper" class="button" >
-       <a href="{{$cr_new_link}}" id="profile-listing-new-link" title="{{$cr_new}}" >{{$cr_new}}</a>
-</div>
-
-<div id="profile-listing-profiles">
-       {{$profiles nofilter}}
-</div>
diff --git a/view/templates/settings/profile/field/edit.tpl b/view/templates/settings/profile/field/edit.tpl
new file mode 100644 (file)
index 0000000..cff4327
--- /dev/null
@@ -0,0 +1,13 @@
+<fieldset data-id="{{$profile_field.id}}">
+       <legend>&#8801; {{$profile_field.legend}}</legend>
+
+       <input type="hidden" name="profile_field_order[]" value="{{$profile_field.id}}">
+
+       {{include file="field_input.tpl" field=$profile_field.fields.label}}
+
+       {{include file="field_textarea.tpl" field=$profile_field.fields.value}}
+       <details>
+               <summary>Permissions</summary>
+               {{$profile_field.fields.acl nofilter}}
+       </details>
+</fieldset>
\ No newline at end of file
diff --git a/view/templates/settings/profile/hide-friends.tpl b/view/templates/settings/profile/hide-friends.tpl
new file mode 100644 (file)
index 0000000..80e6dcb
--- /dev/null
@@ -0,0 +1,3 @@
+<div id="profile-edit-hide-friends-wrapper">
+       {{include file="field_yesno.tpl" field=$yesno}}
+</div>
diff --git a/view/templates/settings/profile/index.tpl b/view/templates/settings/profile/index.tpl
new file mode 100644 (file)
index 0000000..bf98bb1
--- /dev/null
@@ -0,0 +1,117 @@
+<h1>{{$banner}}</h1>
+
+{{$default nofilter}}
+
+<div id="profile-edit-links">
+       <ul>
+               <li><a href="settings/profile/photo" id="profile-photo_upload-link" title="{{$profpic}}">{{$profpic}}</a></li>
+               <li><a href="profile/{{$nickname}}" id="profile-edit-view-link" title="{{$viewprof}}">{{$viewprof}}</a></li>
+       </ul>
+</div>
+
+<div id="profile-edit-links-end"></div>
+
+<div id="profile-edit-wrapper">
+       <form id="profile-edit-form" name="form1" action="settings/profiles" method="post">
+               <input type="hidden" name="form_security_token" value="{{$form_security_token}}">
+
+               <div id="profile-edit-name-wrapper">
+                       <label id="profile-edit-name-label" for="profile-edit-name">{{$name.1}} </label>
+                       <input type="text" size="32" name="name" id="profile-edit-name" value="{{$name.2}}"/>
+               </div>
+               <div id="profile-edit-name-end"></div>
+               <div id="profile-edit-pdesc-wrapper">
+                       <label id="profile-edit-pdesc-label" for="profile-edit-pdesc">{{$pdesc.1}} </label>
+                       <input type="text" size="32" name="pdesc" id="profile-edit-pdesc" value="{{$pdesc.1}}"/>
+               </div>
+               <div id="profile-edit-pdesc-end"></div>
+               <div id="profile-edit-dob-wrapper">
+                       {{$dob nofilter}}
+               </div>
+               <div id="profile-edit-dob-end"></div>
+               {{$hide_friends nofilter}}
+               <div class="profile-edit-submit-wrapper">
+                       <input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
+               </div>
+               <div class="profile-edit-submit-end"></div>
+               <div id="profile-edit-address-wrapper">
+                       <label id="profile-edit-address-label" for="profile-edit-address">{{$address.1}} </label>
+                       <input type="text" size="32" name="address" id="profile-edit-address" value="{{$address.2}}"/>
+               </div>
+               <div id="profile-edit-address-end"></div>
+               <div id="profile-edit-locality-wrapper">
+                       <label id="profile-edit-locality-label" for="profile-edit-locality">{{$locality.1}} </label>
+                       <input type="text" size="32" name="locality" id="profile-edit-locality" value="{{$locality.2}}"/>
+               </div>
+               <div id="profile-edit-locality-end"></div>
+               <div id="profile-edit-postal-code-wrapper">
+                       <label id="profile-edit-postal-code-label" for="profile-edit-postal-code">{{$postal_code.1}} </label>
+                       <input type="text" size="32" name="postal_code" id="profile-edit-postal-code" value="{{$postal_code.2}}"/>
+               </div>
+               <div id="profile-edit-postal-code-end"></div>
+               <div id="profile-edit-country-name-wrapper">
+                       <label id="profile-edit-country-name-label" for="profile-edit-country-name">{{$country_name.1}} </label>
+                       <select name="country_name" id="profile-edit-country-name" onChange="Fill_States('{{$region.2}}');">
+                               <option selected="selected">{{$country_name.2}}</option>
+                               <option>temp</option>
+                       </select>
+               </div>
+               <div id="profile-edit-country-name-end"></div>
+               <div id="profile-edit-region-wrapper">
+                       <label id="profile-edit-region-label" for="profile-edit-region">{{$region.1}} </label>
+                       <select name="region" id="profile-edit-region" onChange="Update_Globals();">
+                               <option selected="selected">{{$region.2}}</option>
+                               <option>temp</option>
+                       </select>
+               </div>
+               <div id="profile-edit-hometown-end"></div>
+               <div class="profile-edit-submit-wrapper">
+                       <input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
+               </div>
+               <div class="profile-edit-submit-end"></div>
+               <div id="profile-edit-homepage-wrapper">
+                       <label id="profile-edit-homepage-label" for="profile-edit-homepage">{{$homepage.1}} </label>
+                       <input type="url" size="32" name="homepage" id="profile-edit-homepage" value="{{$homepage.2}}"/>
+               </div>
+               <div id="profile-edit-homepage-end"></div>
+               <div id="profile-edit-xmpp-wrapper">
+                       <label id="profile-edit-xmpp-label" for="profile-edit-xmpp">{{$xmpp.1}} </label>
+                       <input type="text" size="32" name="xmpp" id="profile-edit-xmpp" title="{{$lbl_ex2}}" value="{{$xmpp.2}}"/>
+               </div>
+               <div id="profile-edit-xmpp-desc">{{$xmpp.3}}</div>
+               <div id="profile-edit-xmpp-end"></div>
+               <div id="profile-edit-pubkeywords-wrapper">
+                       <label id="profile-edit-pubkeywords-label" for="profile-edit-pubkeywords">{{$pub_keywords.1}} </label>
+                       <input type="text" size="32" name="pub_keywords" id="profile-edit-pubkeywords" title="{{$lbl_ex2}}" value="{{$pub_keywords.2}}"/>
+               </div>
+               <div id="profile-edit-pubkeywords-desc">{{$pub_keywords.3}}</div>
+               <div id="profile-edit-pubkeywords-end"></div>
+               <div id="profile-edit-prvkeywords-wrapper">
+                       <label id="profile-edit-prvkeywords-label" for="profile-edit-prvkeywords">{{$prv_keywords.1}} </label>
+                       <input type="text" size="32" name="prv_keywords" id="profile-edit-prvkeywords" title="{{$lbl_ex2}}" value="{{$prv_keywords.2}}"/>
+               </div>
+               <div id="profile-edit-prvkeywords-desc">{{$prv_keywords.3}}</div>
+               <div id="profile-edit-prvkeywords-end"></div>
+               <div class="profile-edit-submit-wrapper">
+                       <input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
+               </div>
+               <div class="profile-edit-submit-end"></div>
+
+               <h3>{{$lbl_custom_fields_section}}</h3>
+               {{$custom_fields_description nofilter}}
+               <div id="profile-custom-fields">
+               {{foreach $custom_fields as $custom_field}}
+                       {{include file="settings/profile/field/edit.tpl" profile_field=$custom_field}}
+               {{/foreach}}
+               </div>
+
+               <div class="profile-edit-submit-wrapper">
+                       <input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
+               </div>
+               <div class="profile-edit-submit-end"></div>
+       </form>
+</div>
+<script type="text/javascript">
+       Fill_Country('{{$country_name.2}}');
+       Fill_States('{{$region.2}}');
+</script>
diff --git a/view/templates/settings/profile/index_head.tpl b/view/templates/settings/profile/index_head.tpl
new file mode 100644 (file)
index 0000000..f7e1fb1
--- /dev/null
@@ -0,0 +1 @@
+<script type="text/javascript" src="view/js/country.js" ></script>
\ No newline at end of file
diff --git a/view/templates/settings/profile/link.tpl b/view/templates/settings/profile/link.tpl
new file mode 100644 (file)
index 0000000..d387ea6
--- /dev/null
@@ -0,0 +1,2 @@
+<div class="profile-edit-side-div"><a class="profile-edit-side-link icon edit" title="{{$editprofile}}" href="settings/profile"></a></div>
+<div class="clear"></div>
index af1352c4cbeb1b5913bdbd56485f8f8d59b788f8..617baeb91a3729d9f4ac4e2672dfc45bc1218e3b 100644 (file)
 <div class="settings-content-block">
 <div id="settings-notifications">
 
-<div id="settings-notify-desc">{{$lbl_not}}</div>
+<div id="settings-notification-desc">{{$lbl_not}}</div>
 
 <div class="group">
 {{include file="field_intcheckbox.tpl" field=$notify1}}
diff --git a/view/templates/suggestions.tpl b/view/templates/suggestions.tpl
deleted file mode 100644 (file)
index 44fe865..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-<div class="intro-wrapper" >
-
-<p class="intro-desc">{{$str_notifytype}} {{$notify_type}}</p>
-{{if $madeby}}<div class="intro-madeby">{{$lbl_madeby}} {{$madeby}}</div>{{/if}}
-<div class="intro-fullname" >{{$fullname}}</div>
-<a class="intro-url-link" href="{{$url}}" ><img class="intro-photo lframe" src="{{$photo}}" width="175" height="175" title="{{$fullname}}" alt="{{$fullname}}" /></a>
-<div class="intro-note" >{{$note}}</div>
-<div class="intro-wrapper-end"></div>
-<form class="intro-form" action="notifications/{{$intro_id}}" method="post">
-<input class="intro-submit-ignore" type="submit" name="submit" value="{{$ignore}}" />
-<input class="intro-submit-discard" type="submit" name="submit" value="{{$discard}}" />
-</form>
-<div class="intro-form-end"></div>
-
-<form class="intro-approve-form" action="{{$request}}" method="get">
-{{include file="field_checkbox.tpl" field=$hidden}}
-<input class="intro-submit-approve" type="submit" name="submit" value="{{$approve}}" />
-</form>
-</div>
-<div class="intro-end"></div>
index 4e0ae7754d6d30d247f31758254e634fccad0111..0ac061b47ebd23d957e02c545ef1be78a84d1406 100644 (file)
                                {{$profile_photo_txt nofilter}}
                        </li>
                        <li>
-                               <a target="newmember" href="profiles">{{$profiles_link}}</a><br />
+                               <a target="newmember" href="settings/profile">{{$profiles_link}}</a><br />
                                {{$profiles_txt nofilter}}
                        </li>
                        <li>
-                               <a target="newmember" href="profiles">{{$profiles_keywords_link}}</a><br />
+                               <a target="newmember" href="settings/profile">{{$profiles_keywords_link}}</a><br />
                                {{$profiles_keywords_txt nofilter}}
                        </li>
                </ul>
index dc021a619bc2022876192927c2bbd6c7485048ad..2e236e5df9cd4cb8b99924d22a44bb82723ff474 100644 (file)
@@ -133,7 +133,7 @@ input#dfrn-url {
   background:#444;
 }
 
-.notify-seen {
+.notification-seen {
   background:#111;
 }
 
index eceaed1247e49d596df0aee4e8b9235ff0325a75..3e8151c5ac1ffc9c130a68688ae471048086feaa 100644 (file)
@@ -646,10 +646,14 @@ input#dfrn-url {
 #profile-edit-links ul {
        list-style-type: none;
 }
-
 #profile-edit-links li {
        margin-top: 10px;
 }
+
+#profile-menu {
+       display: none;
+}
+
 .profile-edit-side-div {
        float: right;
 }
@@ -784,7 +788,7 @@ input#dfrn-url {
 #settings-notifications label {
        margin-left: 20px;
 }
-#settings-notify-desc, #settings-activity-desc {
+#settings-notification-desc, #settings-activity-desc {
        font-weight: bold;
        margin-bottom: 15px;
 }
@@ -2781,7 +2785,7 @@ aside input[type='text'] {
 #crepair-url-label,
 #crepair-request-label,
 #crepair-confirm-label,
-#crepair-notify-label,
+#crepair-notification-label,
 #crepair-photo-label,
 #crepair-poll-label {
        float: left;
@@ -3316,7 +3320,7 @@ div.jGrowl div.info {
   margin-right: -20px;
 }
 
-.nav-notify {
+.nav-notification {
        display: none;
        position: absolute;
        font-size: 10px;
@@ -3326,7 +3330,7 @@ div.jGrowl div.info {
        min-width: 15px;
        text-align: right;
 }
-.nav-notify.show {
+.nav-notification.show {
        display: block;
 }
 #nav-notifications-menu {
@@ -3372,7 +3376,7 @@ div.jGrowl div.info {
        padding: 7px 7px 0px 0px;
 }
 
-.notify-seen {
+.notification-seen {
        background: #DDDDDD;
 }
 
index 3a0db1264bb3d1c1937fde4759d8b2b30e2cab75..bde59784b816b4bcf056632f98c885555016e4bd 100644 (file)
@@ -34,7 +34,7 @@
        <a accesskey="c" id="nav-community-link" class="nav-commlink {{$nav.community.2}} {{$sel.community}}" href="{{$nav.community.0}}" title="{{$nav.community.3}}" >{{$nav.community.1}}</a>
        {{/if}}
        {{if $nav.introductions}}
-       <a id="nav-notify-link" class="nav-commlink {{$nav.introductions.2}} {{$sel.introductions}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >{{$nav.introductions.1}}</a>
+       <a id="nav-notification-link" class="nav-commlink {{$nav.introductions.2}} {{$sel.introductions}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >{{$nav.introductions.1}}</a>
        <span id="intro-update" class="nav-ajax-left"></span>
        {{/if}}
        {{if $nav.messages}}
 
                {{if $nav.notifications}}
                        <a accesskey="f" id="nav-notifications-linkmenu" class="nav-commlink" href="{{$nav.notifications.0}}" rel="#nav-notifications-menu" title="{{$nav.notifications.1}}">{{$nav.notifications.1}}</a>
-                               <span id="notify-update" class="nav-ajax-left"></span>
+                               <span id="notification-update" class="nav-ajax-left"></span>
                                <ul id="nav-notifications-menu" class="menu-popup">
                                        <li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
-                                       <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
+                                       <li id="nav-notifications-mark-all"><a href="#" onclick="notificationMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
                                        <li class="empty">{{$emptynotifications}}</li>
                                </ul>
                {{/if}}         
index fd99a75fad7032a4d58153ba0861f11c6cf5a223..b65c7d6e3847bc6219fd69564a8c48a12eb18480 100644 (file)
@@ -512,7 +512,7 @@ nav.navbar .nav>li>a:focus{
     text-decoration: none;
     text-align: left
 }
-#topbar-first .topbar-nav .nav-segment .nav-notify {
+#topbar-first .topbar-nav .nav-segment .nav-notification {
     position: absolute;
     top: 4px;
     right: -2px;
@@ -640,7 +640,7 @@ nav.navbar a, nav.navbar .btn-link {
     font-size: 12px;
 }
 
-#topbar-first #nav-notifications-menu li.notify-unseen {
+#topbar-first #nav-notifications-menu li.notification-unseen {
     border-left: 3px solid #f3fcfd;
     background-color: #f3fcfd;
 }
@@ -682,7 +682,7 @@ nav.navbar a, nav.navbar .btn-link {
 #topbar-first .account .user-title span {
     color: $nav_icon_color;
 }
-#topbar-first .account #main-menu .nav-notify {
+#topbar-first .account #main-menu .nav-notification {
     position: absolute;
     top: 4px;
     right: -2px;
index 6e76fc85d719f0fdfea8788b9da019c8d6283e7b..1141f43422e57ca86cf184e27254550f6928016f 100644 (file)
@@ -25,7 +25,7 @@ aside .widget, .form-control, .panel, .nav-container, .wall-item-content, .e-con
     font-family: ".SFNSText-Regular","San Francisco","Roboto","Segoe UI","Helvetica Neue","Lucida Grande",Helvetica,Arial,sans-serif;
 }
 
-#topbar-first #nav-notifications-menu li.notify-unseen {
+#topbar-first #nav-notifications-menu li.notification-unseen {
     border-left: 3px solid #f3fcfd;
     background-color: antiquewhite;
 }
index f9454dc654f3d5fdca2e90ed00b999764ef7fe9d..9bf7b3233323702d5cf0b2bddcbd81130d625d20 100644 (file)
                                                </div>
                                        </div>
                                        {{/if}}
-                                       {{if $lbl_vis1}}
-                                       <div class="panel">
-                                               <div class="section-subtitle-wrapper" role="tab" id="contact-edit-profile-select">
-                                                       <h4>
-                                                               <a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#contact-edit-tools" href="#contact-edit-profile-select-collapse" aria-expanded="false" aria-controls="contact-edit-profile-select-collapse">
-                                                                       {{$lbl_vis1}}
-                                                               </a>
-                                                       </h4>
-                                               </div>
-                                               <div id="contact-edit-profile-select-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="contact-edit-profile-select">
-                                                       <div class="section-content-tools-wrapper">
-                                                               {{if $profile_select}}
-                                                                       <div id="contact-edit-profile-select-text">
-                                                                               <p>{{$lbl_vis2}}</p>
-                                                                       </div>
-                                                                       <div class="form-group">
-                                                                       {{$profile_select nofilter}}
-                                                                       </div>
-                                                                       <div class="clear"></div>
-                                                               {{/if}}
-
-                                                               <div class="form-group pull-right settings-submit-wrapper" >
-                                                                       <button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
-                                                               </div>
-                                                               <div class="clear"></div>
-                                                       </div>
-                                               </div>
-                                       </div>
-                                       {{/if}}
                                </div>
 
                        </form>{{* End of the form *}}
diff --git a/view/theme/frio/templates/intros.tpl b/view/theme/frio/templates/intros.tpl
deleted file mode 100644 (file)
index a8a033c..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-
-{{* template incomming contact request and suggested contacts *}}
-
-<div class="intro-wrapper media" id="intro-{{$intro_id}}" >
-
-       {{* Contact Photo *}}
-       <div class="intro-photo-wrapper dropdown pull-left" >
-               <img id="photo-{{$intro_id}}" class="intro-photo media-object" src="{{$photo}}" title="{{$fullname}}" alt="{{$fullname}}" />
-       </div>
-
-       <div class="media-body">
-               {{* The intro actions like approve, ignore, discard intro*}}
-               <div class="intro-actions pull-right nav-pills preferences">
-                       <button class="btn-link intro-action-link" onclick="addElmToModal('#intro-approve-wrapper-{{$intro_id}}');" aria-label="{{$approve}}" title="{{$approve}}" data-toggle="tooltip"><i class="fa fa-check" aria-hidden="true"></i></button>
-
-                       <form class="intro-form" action="notifications/{{$intro_id}}" method="post">
-                               <button class="btn-link intro-submit-ignore intro-action-link" type="submit" name="submit" value="{{$ignore}}" aria-label="{{$ignore}}" title="{{$ignore}}" data-toggle="tooltip"><i class="fa fa-ban" aria-hidden="true"></i></button>
-                               {{if $discard}}<button class="btn-link intro-submit-discard intro-action-link" type="submit" name="submit" value="{{$discard}}" aria-label="{{$discard}}" title="{{$discard}}" data-toggle="tooltip"><i class="fa fa-trash-o" aria-hidden="true"></i></button>{{/if}}
-                       </form>
-               </div>
-               <div class='intro-enty-name'><h4 class="media-heading"><a href="{{$zrl}}">{{$fullname}}</a></h4></div>
-               <div class="intro-desc"><span class="intro-desc-label">{{$str_notifytype}}</span>&nbsp;{{$notify_type}}</div>
-               {{* if the contact was suggestested by another contact, the contact who made the suggestion is displayed*}}
-               {{if $madeby}}<div class="intro-madeby"><span class="intro-madeby-label">{{$lbl_madeby}}</span>&nbsp;<a href="{{$madeby_zrl}}">{{$madeby}}</a></div>{{/if}}
-
-               {{* Additional information of the contact *}}
-               <div class="intro-contact-info hidden-xs">
-                       <div class="intro-url"><span class="intro-url-label">{{$lbl_url}}:&nbsp;</span><a href="{{$zrl}}">{{$url}}</a></div>
-                       {{if $network}}<div class="intro-network"><span class="intro-network-label">{{$lbl_network}}</span>&nbsp;{{$network}}</div>{{/if}}
-                       {{if $location}}<div class="intro-location"><span class="intro-location-label">{{$lbl_location}}</span>&nbsp;{{$location}}</div>{{/if}}
-                       {{if $gender}}<div class="intro-gender"><span class="intro-gender-label">{{$lbl_gender}}</span>&nbsp;{{$gender}}</div>{{/if}}
-                       {{if $keywords}}<div class="intro-keywords"><span class="intro-keywords-label">{{$lbl_keywords}}</span>&nbsp;{{$keywords}}</div>{{/if}}
-                       {{if $about}}<div class="intro-about"><span class="intro-about-label">{{$lbl_about}}</span>&nbsp;{{$about nofilter}}</div>{{/if}}
-                       <div class="intro-knowyou"><span class="intro-knowyou-label">{{$lbl_knowyou}}</span>{{$knowyou}}</div>
-                       <div class="intro-note intro-note-{{$intro_id}}">{{$note}}</div>
-               </div>
-
-               {{* Additional information of the contact for mobile view *}}
-               <div class="intro-contact-info xs hidden-lg hidden-md hidden-sm">
-                       <div class="intro-url"><span class="intro-url-label">{{$lbl_url}}:</span><a href="{{$zrl}}">{{$url}}</a></div>
-                       {{if $network}}<div class="intro-network"><span class="intro-network-label">{{$lbl_network}}</span>{{$network}}</div>{{/if}}
-                       {{if $location}}<div class="intro-location"><span class="intro-location-label">{{$lbl_location}}</span>{{$location}}</div>{{/if}}
-                       {{if $gender}}<div class="intro-gender"><span class="intro-gender-label">{{$lbl_gender}}</span>{{$gender}}</div>{{/if}}
-                       {{if $keywords}}<div class="intro-keywords"><span class="intro-keywords-label">{{$lbl_keywords}}</span>{{$keywords}}</div>{{/if}}
-                       {{if $about}}<div class="intro-about"><span class="intro-about-label">{{$lbl_about}}</span>{{$about nofilter}}</div>{{/if}}
-                       <div class="intro-knowyou"><span class="intro-knowyou-label">{{$lbl_knowyou}}</span>{{$knowyou}}</div>
-                       <div class="intro-note intro-note-{{$intro_id}}">{{$note}}</div>
-               </div>
-
-               {{* This sections contains special settings for contact approval. We hide it by default and load this section in
-               a bootstrap modal in the case of approval *}}
-               <div id="intro-approve-wrapper-{{$intro_id}}" style="display: none;">
-
-                       <h3 class="heading">{{$fullname}}{{if $addr}}&nbsp;({{$addr}}){{/if}}</h3>
-                       <form class="intro-approve-form" {{if $request}}action="{{$request}}" method="get"{{else}}action="{{$action}}" method="post"{{/if}}>
-                               {{include file="field_checkbox.tpl" field=$hidden}}
-                               {{if $type != "friend_suggestion"}}
-                               <input type="hidden" name="dfrn_id" value="{{$dfrn_id}}" >
-                               <input type="hidden" name="intro_id" value="{{$intro_id}}" >
-                               <input type="hidden" name="contact_id" value="{{$contact_id}}" >
-                               {{/if}}
-
-                               {{$dfrn_text nofilter}}
-
-                               <div class="pull-right">
-                                       <button class="btn btn-primary intro-submit-approve" type="submit" name="submit" value="{{$approve}}">{{$approve}}</button>
-                               </div>
-                               <div class="clear"></div>
-                       </form>
-               </div>
-       </div>
-
-       {{* On mobile touch devices we use buttons for approve, ingnore && discard to have a better UX *}}
-       {{if $APP->is_mobile}}
-       <div class="intro-action-buttons">
-               <form class="intro-form pull-left" action="notifications/{{$intro_id}}" method="post">
-                       <button class="btn btn-small btn-default intro-submit-ignore" type="submit" name="submit" value="{{$ignore}}">{{$ignore}}</button>
-                       {{if $discard}}<button class="btn btn-small btn-default intro-submit-discard" type="submit" name="submit" value="{{$discard}}">{{$discard}}</button>&nbsp;{{/if}}
-               </form>
-               <button class="btn btn-small btn-primary intro-submit-approve pull-right" onclick="addElmToModal('#intro-approve-wrapper-{{$intro_id}}')">{{$approve}}</button>
-       </div>
-       <div class="clear"></div>
-       {{/if}}
-</div>
-<div class="intro-end"></div>
index a2b5106a61c120039135219e0d032183ef957919..3f13bd355d344e0a70cb0a580d31dc744d951580 100644 (file)
                                <ul class="nav navbar-nav navbar-left" role="menubar">
                                        <li id="nav-communication" class="nav-segment" role="presentation">
                                                {{if $nav.network}}
-                                               <a accesskey="n" role="menuitem" class="nav-menu {{$sel.network}}" href="{{$nav.network.0}}" data-toggle="tooltip" aria-label="{{$nav.network.3}}" title="{{$nav.network.3}}"><i class="fa fa-lg fa-th" aria-hidden="true"></i><span id="net-update" class="nav-network-badge badge nav-notify"></span></a>
+                                               <a accesskey="n" role="menuitem" class="nav-menu {{$sel.network}}" href="{{$nav.network.0}}" data-toggle="tooltip" aria-label="{{$nav.network.3}}" title="{{$nav.network.3}}"><i class="fa fa-lg fa-th" aria-hidden="true"></i><span id="net-update" class="nav-network-badge badge nav-notification"></span></a>
                                                {{/if}}
 
                                                {{if $nav.home}}
-                                               <a accesskey="p" role="menuitem" class="nav-menu {{$sel.home}}" href="{{$nav.home.0}}" data-toggle="tooltip" aria-label="{{$nav.home.3}}" title="{{$nav.home.3}}"><i class="fa fa-lg fa-home" aria-hidden="true"></i><span id="home-update" class="nav-home-badge badge nav-notify"></span></a>
+                                               <a accesskey="p" role="menuitem" class="nav-menu {{$sel.home}}" href="{{$nav.home.0}}" data-toggle="tooltip" aria-label="{{$nav.home.3}}" title="{{$nav.home.3}}"><i class="fa fa-lg fa-home" aria-hidden="true"></i><span id="home-update" class="nav-home-badge badge nav-notification"></span></a>
                                                {{/if}}
 
                                                {{if $nav.community}}
@@ -54,7 +54,7 @@
 
                                        <li id="nav-personal" class="nav-segment hidden-xs" role="presentation">
                                                {{if $nav.messages}}
-                                               <a role="menuitem" id="nav-messages-link" href="{{$nav.messages.0}}" data-toggle="tooltip" aria-label="{{$nav.messages.1}}" title="{{$nav.messages.1}}" class="nav-menu {{$sel.messages}}"><i class="fa fa-envelope fa-lg" aria-hidden="true"></i><span id="mail-update" class="nav-mail-badge badge nav-notify"></span></a>
+                                               <a role="menuitem" id="nav-messages-link" href="{{$nav.messages.0}}" data-toggle="tooltip" aria-label="{{$nav.messages.1}}" title="{{$nav.messages.1}}" class="nav-menu {{$sel.messages}}"><i class="fa fa-envelope fa-lg" aria-hidden="true"></i><span id="mail-update" class="nav-mail-badge badge nav-notification"></span></a>
                                                {{/if}}
 
                                                {{if $nav.events}}
@@ -63,7 +63,7 @@
 
                                                {{if $nav.contacts}}
                                                <a role="menuitem" id="nav-contacts-link" class="nav-menu {{$sel.contacts}} {{$nav.contacts.2}}" href="{{$nav.contacts.0}}" data-toggle="tooltip" aria-label="{{$nav.contacts.1}}" title="{{$nav.contacts.1}}" ><i class="fa fa-users fa-lg" aria-hidden="true"></i></a>
-                                               <span id="intro-update" class="nav-intro-badge badge nav-notify" onclick="window.location.href = '{{$nav.introductions.0}}' " data-toggle="tooltip" aria-label="{{$nav.introductions.3}}" title="{{$nav.introductions.3}}"></span>
+                                               <span id="intro-update" class="nav-intro-badge badge nav-notification" onclick="window.location.href = '{{$nav.introductions.0}}' " data-toggle="tooltip" aria-label="{{$nav.introductions.3}}" title="{{$nav.introductions.3}}"></span>
                                                {{/if}}
                                        </li>
 
@@ -73,7 +73,7 @@
                                                        <a href="{{$nav.notifications.0}}" rel="#nav-notifications-menu" data-toggle="tooltip" aria-label="{{$nav.notifications.1}}" title="{{$nav.notifications.1}}" role="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-controls="nav-notifications-menu">
                                                                <i class="fa fa-bell fa-lg" aria-hidden="true"></i>
                                                                <span role="menuitem" class="sr-only">{{$nav.notifications.1}}</span>
-                                                               <span id="notify-update" class="nav-notify-badge badge nav-notify dropdown" data-toggle="dropdown"></span>
+                                                               <span id="notification-update" class="nav-notification-badge badge nav-notification dropdown" data-toggle="dropdown"></span>
                                                        </a>
 
                                                        {{* The notifications dropdown menu. There are two parts of menu. The second is at the bottom of this file. It is loaded via js. Look at nav-notifications-template *}}
@@ -84,7 +84,7 @@
                                                                        <div class="arrow"></div>
                                                                        {{$nav.notifications.1}}
                                                                        <div class="dropdown-header-link">
-                                                                               <button role="menuitem" type="button" class="btn-link" onclick="notifyMarkAll();" data-toggle="tooltip" aria-label="{{$nav.notifications.mark.3}}" title="{{$nav.notifications.mark.3}}">{{$nav.notifications.mark.1}}</button>
+                                                                               <button role="menuitem" type="button" class="btn-link" onclick="notificationMarkAll();" data-toggle="tooltip" aria-label="{{$nav.notifications.mark.3}}" title="{{$nav.notifications.mark.3}}">{{$nav.notifications.mark.1}}</button>
                                                                        </div>
 
                                                                </li>
                                                        <li role="presentation"><a role="menuitem" href="{{$nav.notifications.all.0}}" title="{{$nav.notifications.1}}"><i class="fa fa-bell fa-fw" aria-hidden="true"></i> {{$nav.notifications.1}}</a></li>
                                                        {{/if}}
                                                        {{if $nav.messages}}
-                                                       <li role="presentation"><a role="menuitem" class="nav-commlink {{$nav.messages.2}} {{$sel.messages}}" href="{{$nav.messages.0}}" title="{{$nav.messages.3}}" ><i class="fa fa-envelope fa-fw" aria-hidden="true"></i> {{$nav.messages.1}} <span id="mail-update-li" class="nav-mail-badge badge nav-notify"></span></a></li>
+                                                       <li role="presentation"><a role="menuitem" class="nav-commlink {{$nav.messages.2}} {{$sel.messages}}" href="{{$nav.messages.0}}" title="{{$nav.messages.3}}" ><i class="fa fa-envelope fa-fw" aria-hidden="true"></i> {{$nav.messages.1}} <span id="mail-update-li" class="nav-mail-badge badge nav-notification"></span></a></li>
                                                        {{/if}}
                                                        <li role="presentation" class="divider"></li>
                                                        {{if $nav.contacts}}
-                                                       <li role="presentation"><a role="menuitem" id="nav-menu-contacts-link" class="nav-link {{$nav.contacts.2}}" href="{{$nav.contacts.0}}" title="{{$nav.contacts.3}}"><i class="fa fa-users fa-fw" aria-hidden="true"></i> {{$nav.contacts.1}}</a><span id="intro-update-li" class="nav-intro-badge badge nav-notify"></span></li>
+                                                       <li role="presentation"><a role="menuitem" id="nav-menu-contacts-link" class="nav-link {{$nav.contacts.2}}" href="{{$nav.contacts.0}}" title="{{$nav.contacts.3}}"><i class="fa fa-users fa-fw" aria-hidden="true"></i> {{$nav.contacts.1}}</a><span id="intro-update-li" class="nav-intro-badge badge nav-notification"></span></li>
                                                        {{/if}}
                                                        {{if $nav.delegation}}
                                                        <li role="presentation"><a role="menuitem" id="nav-delegation-link" class="nav-commlink {{$nav.delegation.2}} {{$sel.delegation}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}"><i class="fa fa-flag fa-fw" aria-hidden="true"></i> {{$nav.delegation.1}}</a></li>
diff --git a/view/theme/frio/templates/notifications.tpl b/view/theme/frio/templates/notifications.tpl
deleted file mode 100644 (file)
index 1be92c4..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-<script type="text/javascript" src="view/theme/frio/frameworks/jquery-color/jquery.color.js"></script>
-<script type="text/javascript" src="view/theme/frio/js/mod_notifications.js"></script>
-
-<div class="generic-page-wrapper">
-       {{include file="section_title.tpl" title=$notif_header}}
-
-       {{if $tabs }}{{include file="common_tabs.tpl"}}{{/if}}
-
-       <div class="notif-network-wrapper">
-               {{* The "show ignored" link *}}
-               {{if $notif_show_lnk}}<a href="{{$notif_show_lnk.href}}" id="notifications-show-hide-link">{{$notif_show_lnk.text}}</a>{{/if}}
-
-               {{* The notifications *}}
-               {{if $notif_content}}
-               <ul class="notif-network-list media-list">
-               {{foreach $notif_content as $notification}}
-                       <li>{{$notification nofilter}}</li>
-               {{/foreach}}
-               </ul>
-               {{/if}}
-
-               {{* If no notifications messages available *}}
-               {{if $notif_nocontent}}
-               <div class="notif_nocontent">{{$notif_nocontent}}</div>
-               {{/if}}
-       </div>
-
-       {{* The pager *}}
-       {{$notif_paginate nofilter}}
-</div>
diff --git a/view/theme/frio/templates/notifications/attend_item.tpl b/view/theme/frio/templates/notifications/attend_item.tpl
new file mode 100644 (file)
index 0000000..bb88e87
--- /dev/null
@@ -0,0 +1,2 @@
+
+{{include file="notifications/notification.tpl"}}
diff --git a/view/theme/frio/templates/notifications/comments_item.tpl b/view/theme/frio/templates/notifications/comments_item.tpl
new file mode 100644 (file)
index 0000000..bb88e87
--- /dev/null
@@ -0,0 +1,2 @@
+
+{{include file="notifications/notification.tpl"}}
diff --git a/view/theme/frio/templates/notifications/dislikes_item.tpl b/view/theme/frio/templates/notifications/dislikes_item.tpl
new file mode 100644 (file)
index 0000000..bb88e87
--- /dev/null
@@ -0,0 +1,2 @@
+
+{{include file="notifications/notification.tpl"}}
diff --git a/view/theme/frio/templates/notifications/friends_item.tpl b/view/theme/frio/templates/notifications/friends_item.tpl
new file mode 100644 (file)
index 0000000..bb88e87
--- /dev/null
@@ -0,0 +1,2 @@
+
+{{include file="notifications/notification.tpl"}}
diff --git a/view/theme/frio/templates/notifications/intros.tpl b/view/theme/frio/templates/notifications/intros.tpl
new file mode 100644 (file)
index 0000000..4bab6fa
--- /dev/null
@@ -0,0 +1,85 @@
+
+{{* template incomming contact request and suggested contacts *}}
+
+<div class="intro-wrapper media" id="intro-{{$intro_id}}" >
+
+       {{* Contact Photo *}}
+       <div class="intro-photo-wrapper dropdown pull-left" >
+               <img id="photo-{{$intro_id}}" class="intro-photo media-object" src="{{$photo}}" title="{{$fullname}}" alt="{{$fullname}}" />
+       </div>
+
+       <div class="media-body">
+               {{* The intro actions like approve, ignore, discard intro*}}
+               <div class="intro-actions pull-right nav-pills preferences">
+                       <button class="btn-link intro-action-link" onclick="addElmToModal('#intro-approve-wrapper-{{$intro_id}}');" aria-label="{{$approve}}" title="{{$approve}}" data-toggle="tooltip"><i class="fa fa-check" aria-hidden="true"></i></button>
+
+                       <form class="intro-form" action="notifications/{{$intro_id}}" method="post">
+                               <button class="btn-link intro-submit-ignore intro-action-link" type="submit" name="submit" value="{{$ignore}}" aria-label="{{$ignore}}" title="{{$ignore}}" data-toggle="tooltip"><i class="fa fa-ban" aria-hidden="true"></i></button>
+                               {{if $discard}}<button class="btn-link intro-submit-discard intro-action-link" type="submit" name="submit" value="{{$discard}}" aria-label="{{$discard}}" title="{{$discard}}" data-toggle="tooltip"><i class="fa fa-trash-o" aria-hidden="true"></i></button>{{/if}}
+                       </form>
+               </div>
+               <div class='intro-enty-name'><h4 class="media-heading"><a href="{{$zrl}}">{{$fullname}}</a></h4></div>
+               <div class="intro-desc"><span class="intro-desc-label">{{$str_notification_type}}</span>&nbsp;{{$str_type}}</div>
+               {{* if the contact was suggestested by another contact, the contact who made the suggestion is displayed*}}
+               {{if $madeby}}<div class="intro-madeby"><span class="intro-madeby-label">{{$lbl_madeby}}</span>&nbsp;<a href="{{$madeby_zrl}}">{{$madeby}}</a></div>{{/if}}
+
+               {{* Additional information of the contact *}}
+               <div class="intro-contact-info hidden-xs">
+                       <div class="intro-url"><span class="intro-url-label">{{$lbl_url}}:&nbsp;</span><a href="{{$zrl}}">{{$url}}</a></div>
+                       {{if $network}}<div class="intro-network"><span class="intro-network-label">{{$lbl_network}}</span>&nbsp;{{$network}}</div>{{/if}}
+                       {{if $location}}<div class="intro-location"><span class="intro-location-label">{{$lbl_location}}</span>&nbsp;{{$location}}</div>{{/if}}
+                       {{if $gender}}<div class="intro-gender"><span class="intro-gender-label">{{$lbl_gender}}</span>&nbsp;{{$gender}}</div>{{/if}}
+                       {{if $keywords}}<div class="intro-keywords"><span class="intro-keywords-label">{{$lbl_keywords}}</span>&nbsp;{{$keywords}}</div>{{/if}}
+                       {{if $about}}<div class="intro-about"><span class="intro-about-label">{{$lbl_about}}</span>&nbsp;{{$about nofilter}}</div>{{/if}}
+                       <div class="intro-knowyou"><span class="intro-knowyou-label">{{$lbl_knowyou}}</span>{{$knowyou}}</div>
+                       <div class="intro-note intro-note-{{$intro_id}}">{{$note}}</div>
+               </div>
+
+               {{* Additional information of the contact for mobile view *}}
+               <div class="intro-contact-info xs hidden-lg hidden-md hidden-sm">
+                       <div class="intro-url"><span class="intro-url-label">{{$lbl_url}}:</span><a href="{{$zrl}}">{{$url}}</a></div>
+                       {{if $network}}<div class="intro-network"><span class="intro-network-label">{{$lbl_network}}</span>{{$network}}</div>{{/if}}
+                       {{if $location}}<div class="intro-location"><span class="intro-location-label">{{$lbl_location}}</span>{{$location}}</div>{{/if}}
+                       {{if $gender}}<div class="intro-gender"><span class="intro-gender-label">{{$lbl_gender}}</span>{{$gender}}</div>{{/if}}
+                       {{if $keywords}}<div class="intro-keywords"><span class="intro-keywords-label">{{$lbl_keywords}}</span>{{$keywords}}</div>{{/if}}
+                       {{if $about}}<div class="intro-about"><span class="intro-about-label">{{$lbl_about}}</span>{{$about nofilter}}</div>{{/if}}
+                       <div class="intro-knowyou"><span class="intro-knowyou-label">{{$lbl_knowyou}}</span>{{$knowyou}}</div>
+                       <div class="intro-note intro-note-{{$intro_id}}">{{$note}}</div>
+               </div>
+
+               {{* This sections contains special settings for contact approval. We hide it by default and load this section in
+               a bootstrap modal in the case of approval *}}
+               <div id="intro-approve-wrapper-{{$intro_id}}" style="display: none;">
+
+                       <h3 class="heading">{{$fullname}}{{if $addr}}&nbsp;({{$addr}}){{/if}}</h3>
+                       <form class="intro-approve-form" {{if $request}}action="{{$request}}" method="get"{{else}}action="{{$action}}" method="post"{{/if}}>
+                               {{include file="field_checkbox.tpl" field=$hidden}}
+                               {{if $type != "friend_suggestion"}}
+                               <input type="hidden" name="dfrn_id" value="{{$dfrn_id}}" >
+                               <input type="hidden" name="intro_id" value="{{$intro_id}}" >
+                               <input type="hidden" name="contact_id" value="{{$contact_id}}" >
+                               {{/if}}
+
+                               {{$dfrn_text nofilter}}
+
+                               <div class="pull-right">
+                                       <button class="btn btn-primary intro-submit-approve" type="submit" name="submit" value="{{$approve}}">{{$approve}}</button>
+                               </div>
+                               <div class="clear"></div>
+                       </form>
+               </div>
+       </div>
+
+       {{* On mobile touch devices we use buttons for approve, ingnore && discard to have a better UX *}}
+       {{if $APP->is_mobile}}
+       <div class="intro-action-buttons">
+               <form class="intro-form pull-left" action="notifications/{{$intro_id}}" method="post">
+                       <button class="btn btn-small btn-default intro-submit-ignore" type="submit" name="submit" value="{{$ignore}}">{{$ignore}}</button>
+                       {{if $discard}}<button class="btn btn-small btn-default intro-submit-discard" type="submit" name="submit" value="{{$discard}}">{{$discard}}</button>&nbsp;{{/if}}
+               </form>
+               <button class="btn btn-small btn-primary intro-submit-approve pull-right" onclick="addElmToModal('#intro-approve-wrapper-{{$intro_id}}')">{{$approve}}</button>
+       </div>
+       <div class="clear"></div>
+       {{/if}}
+</div>
+<div class="intro-end"></div>
diff --git a/view/theme/frio/templates/notifications/likes_item.tpl b/view/theme/frio/templates/notifications/likes_item.tpl
new file mode 100644 (file)
index 0000000..bb88e87
--- /dev/null
@@ -0,0 +1,2 @@
+
+{{include file="notifications/notification.tpl"}}
diff --git a/view/theme/frio/templates/notifications/network_item.tpl b/view/theme/frio/templates/notifications/network_item.tpl
new file mode 100644 (file)
index 0000000..bb88e87
--- /dev/null
@@ -0,0 +1,2 @@
+
+{{include file="notifications/notification.tpl"}}
diff --git a/view/theme/frio/templates/notifications/notifications.tpl b/view/theme/frio/templates/notifications/notifications.tpl
new file mode 100644 (file)
index 0000000..62c0744
--- /dev/null
@@ -0,0 +1,30 @@
+<script type="text/javascript" src="../../frameworks/jquery-color/jquery.color.js"></script>
+<script type="text/javascript" src="../../js/mod_notifications.js"></script>
+
+<div class="generic-page-wrapper">
+       {{include file="section_title.tpl" title=$header}}
+
+       {{if $tabs }}{{include file="common_tabs.tpl"}}{{/if}}
+
+       <div class="notif-network-wrapper">
+               {{* The "show ignored" link *}}
+               {{if $showLink}}<a href="{{$showLink.href}}" id="notifications-show-hide-link">{{$showLink.text}}</a>{{/if}}
+
+               {{* The notifications *}}
+               {{if $notifications}}
+               <ul class="notif-network-list media-list">
+               {{foreach $notifications as $notification}}
+                       <li>{{$notification nofilter}}</li>
+               {{/foreach}}
+               </ul>
+               {{/if}}
+
+               {{* If no notifications messages available *}}
+               {{if $noContent}}
+               <div class="notification_nocontent">{{$noContent}}</div>
+               {{/if}}
+       </div>
+
+       {{* The pager *}}
+       {{$paginate nofilter}}
+</div>
diff --git a/view/theme/frio/templates/notifications/notify.tpl b/view/theme/frio/templates/notifications/notify.tpl
new file mode 100644 (file)
index 0000000..58f3b0d
--- /dev/null
@@ -0,0 +1,12 @@
+
+<div class="notif-item {{if !$item_seen}}unseen{{/if}} {{$item_label}} media">
+       <div class="notif-photo-wrapper media-object pull-left">
+               <a class="userinfo click-card" href="{{$item_url}}"><img src="{{$item_image}}" class="notif-image"></a>
+       </div>
+       <div class="notif-desc-wrapper media-body">
+               <a href="{{$item_link}}">
+                       {{$item_text nofilter}}
+                       <div><time class="notif-when time" data-toggle="tooltip" title="{{$item_when}}">{{$item_ago}}</time></div>
+               </a>
+       </div>
+</div>
diff --git a/view/theme/frio/templates/notifications/posts_item.tpl b/view/theme/frio/templates/notifications/posts_item.tpl
new file mode 100644 (file)
index 0000000..bb88e87
--- /dev/null
@@ -0,0 +1,2 @@
+
+{{include file="notifications/notification.tpl"}}
diff --git a/view/theme/frio/templates/notifications/suggestions.tpl b/view/theme/frio/templates/notifications/suggestions.tpl
new file mode 100644 (file)
index 0000000..9595190
--- /dev/null
@@ -0,0 +1,2 @@
+
+{{include file="notifications/intros.tpl"}}
\ No newline at end of file
diff --git a/view/theme/frio/templates/notifications_attend_item.tpl b/view/theme/frio/templates/notifications_attend_item.tpl
deleted file mode 100644 (file)
index 680b29a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-{{include file="notify.tpl"}}
diff --git a/view/theme/frio/templates/notifications_comments_item.tpl b/view/theme/frio/templates/notifications_comments_item.tpl
deleted file mode 100644 (file)
index 680b29a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-{{include file="notify.tpl"}}
diff --git a/view/theme/frio/templates/notifications_dislikes_item.tpl b/view/theme/frio/templates/notifications_dislikes_item.tpl
deleted file mode 100644 (file)
index 680b29a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-{{include file="notify.tpl"}}
diff --git a/view/theme/frio/templates/notifications_friends_item.tpl b/view/theme/frio/templates/notifications_friends_item.tpl
deleted file mode 100644 (file)
index 680b29a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-{{include file="notify.tpl"}}
diff --git a/view/theme/frio/templates/notifications_likes_item.tpl b/view/theme/frio/templates/notifications_likes_item.tpl
deleted file mode 100644 (file)
index 680b29a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-{{include file="notify.tpl"}}
diff --git a/view/theme/frio/templates/notifications_network_item.tpl b/view/theme/frio/templates/notifications_network_item.tpl
deleted file mode 100644 (file)
index 680b29a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-{{include file="notify.tpl"}}
diff --git a/view/theme/frio/templates/notifications_posts_item.tpl b/view/theme/frio/templates/notifications_posts_item.tpl
deleted file mode 100644 (file)
index 680b29a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-{{include file="notify.tpl"}}
diff --git a/view/theme/frio/templates/notify.tpl b/view/theme/frio/templates/notify.tpl
deleted file mode 100644 (file)
index 58f3b0d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-
-<div class="notif-item {{if !$item_seen}}unseen{{/if}} {{$item_label}} media">
-       <div class="notif-photo-wrapper media-object pull-left">
-               <a class="userinfo click-card" href="{{$item_url}}"><img src="{{$item_image}}" class="notif-image"></a>
-       </div>
-       <div class="notif-desc-wrapper media-body">
-               <a href="{{$item_link}}">
-                       {{$item_text nofilter}}
-                       <div><time class="notif-when time" data-toggle="tooltip" title="{{$item_when}}">{{$item_ago}}</time></div>
-               </a>
-       </div>
-</div>
diff --git a/view/theme/frio/templates/profile/advanced.tpl b/view/theme/frio/templates/profile/advanced.tpl
deleted file mode 100644 (file)
index 3ca4000..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-<div id="profile-page" class="generic-page-wrapper">
-       <h3 class="">{{$title}}</h3>
-
-       {{* The link to edit the profile*}}
-       {{if $profile.edit}}
-       <ul class="nav nav-pills preferences">
-               <li class="pull-right">
-                       <a class="btn btn-link btn-sm" type="button" id="profile-edit-link" href="{{$profile.edit.0}}" title="{{$profile.edit.3}}">
-                               <i class="fa fa-pencil-square-o" aria-hidden="true"></i>&nbsp;{{$profile.edit.1}}
-                       </a>
-               </li>
-       </ul>
-       <div class="clear"></div>
-       {{/if}}
-
-       {{* Frio does split the profile information in "standard" and "advanced". This is the tab menu for swithching between this modes *}}
-       <ul id="profile-menu" class="nav nav-tabs" role="tablist">
-               <li role="presentation" class="active">
-                       <a href="#profile-content-standard" aria-controls="profile-content-standard" role="tab" data-toggle="tab">{{$basic}}</a>
-               </li>
-               <li role="presentation">
-                       <a href="#profile-content-advanced" aria-controls="profile-content-advanced" role="tab" data-toggle="tab">{{$advanced}}</a>
-               </li>
-       </ul>
-
-       <div class="tab-content">
-               <div role="tabpanel" class="tab-pane active" id="profile-content-standard">
-                       <div id="aprofile-fullname" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.fullname.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.fullname.1}}</div>
-                       </div>
-
-                       {{if $profile.membersince}}
-                       <div id="aprofile-membersince" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.membersince.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.membersince.1}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.gender}}
-                       <div id="aprofile-gender" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.gender.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.gender.1}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.birthday}}
-                       <div id="aprofile-birthday" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.birthday.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.birthday.1}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.age}}
-                       <div id="aprofile-age" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.age.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.age.1}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.hometown}}
-                       <div id="aprofile-hometown" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.hometown.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.hometown.1}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.marital}}
-                       <div id="aprofile-marital" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted"><span class="heart">&hearts;</span>  {{$profile.marital.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.marital.1}}{{if $profile.marital.with}} ({{$profile.marital.with nofilter}}){{/if}}{{if $profile.howlong}} {{$profile.howlong}}{{/if}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.homepage}}
-                       <div id="aprofile-homepage" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.homepage.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.homepage.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.about}}
-                       <div id="aprofile-about" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.about.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.about.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.pub_keywords}}
-                       <div id="aprofile-tags" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.pub_keywords.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.pub_keywords.1}}</div>
-                       </div>
-                       {{/if}}
-               </div>
-
-               <div role="tabpanel" class="tab-pane advanced" id="profile-content-advanced">
-                       {{if $profile.sexual}}
-                       <div id="aprofile-sexual" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.sexual.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.sexual.1}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.politic}}
-                       <div id="aprofile-politic" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.politic.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.politic.1}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.religion}}
-                       <div id="aprofile-religion" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.religion.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.religion.1}}</div>
-                       </div>
-                       {{/if}}
-
-
-                       {{if $profile.interest}}
-                       <div id="aprofile-interest" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.interest.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.interest.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.likes}}
-                       <div id="aprofile-likes" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.likes.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.likes.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.dislikes}}
-                       <div id="aprofile-dislikes" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.dislikes.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.dislikes.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.contact}}
-                       <div id="aprofile-contact" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.contact.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.contact.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.music}}
-                       <div id="aprofile-music" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.music.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.music.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-
-
-                       {{if $profile.book}}
-                       <div id="aprofile-book" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.book.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.book.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-
-
-                       {{if $profile.tv}}
-                       <div id="aprofile-tv" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.tv.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.tv.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-
-
-                       {{if $profile.film}}
-                       <div id="aprofile-film" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.film.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.film.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-
-
-                       {{if $profile.romance}}
-                       <div id="aprofile-romance" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.romance.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.romance.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-
-
-                       {{if $profile.work}}
-                       <div id="aprofile-work" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                       <hr class="profile-separator">
-                       <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.work.0}}</div>
-                       <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.work.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.education}}
-                       <div id="aprofile-education" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.education.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.education.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-
-                       {{if $profile.forumlist}}
-                       <div id="aprofile-forumlist" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 aprofile">
-                               <hr class="profile-separator">
-                               <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 profile-label-name text-muted">{{$profile.forumlist.0}}</div>
-                               <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12 profile-entry">{{$profile.forumlist.1 nofilter}}</div>
-                       </div>
-                       {{/if}}
-               </div>
-       </div>
-</div>
diff --git a/view/theme/frio/templates/profile_edit.tpl b/view/theme/frio/templates/profile_edit.tpl
deleted file mode 100644 (file)
index 946443c..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-
-<div class="generic-page-wrapper">
-       {{include file="section_title.tpl" title=$banner}}
-
-       {{* The actions dropdown which can performed to the current profile *}}
-       <div id="profile-edit-links">
-               <ul class="nav nav-pills preferences">
-                       <li class="dropdown pull-right">
-                               <button type="button" class="btn btn-link btn-sm dropdown-toggle" id="profile-edit-links-dropdown" data-toggle="dropdown" aria-expanded="false">
-                                       <i class="fa fa-angle-down"  aria-hidden="true"></i>&nbsp;{{$profile_action}}
-                               </button>
-                               <ul class="dropdown-menu pull-right" role="menu" aria-labelledby="profile-edit-links-dropdown">
-                                       <li role="presentation"><a role="menuitem" href="{{$profpiclink}}" id="profile-photo_upload-link" title="{{$profpic}}"><i class="fa fa-user" aria-hidden="true"></i>&nbsp;{{$profpic}}</a></li>
-                                       <li role="presentation"><button role="menuitem" type="button" class="btn-link" id="profile-photo_upload-link-new" title="{{$lbl_profile_photo}}" onclick="openClose('profile-photo-upload-section');"><i class="fa fa-user" aria-hidden="true"></i>&nbsp;{{$lbl_profile_photo}}</button></li>
-                                       {{if ! $is_default}}
-                                       <li role="presentation" class="nav-item"><a role="menuitem" href="profperm/{{$profile_id}}" id="profile-edit-visibility-link" title="{{$editvis}}"><i class="fa fa-pencil" aria-hidden="true"></i>&nbsp;{{$editvis}}</a>
-                                       </li>
-                                       {{/if}}
-                                       <li role="presentation" class="divider"></li>
-                                       <li role="presentation"><a role="menuitem" href="profile/{{$profile_id}}/view?tab=profile" id="profile-edit-view-link" title="{{$viewprof}}">{{$viewprof}}</a></li>
-                                       <li role="presentation"><a role="menuitem" href="profiles" id="profile-edit-view-link" title="{{$viewallprof}}">{{$viewallprof}}</a></li>
-                                       {{if $profile_clone_link}}
-                                       <li role="presentation" class="divider"></li>
-                                       <li role="presentation"><a role="menuitem" href="{{$profile_clone_link}}" id="profile-edit-clone-link" title="{{$cr_prof}}">{{$cl_prof}}</a></li>
-                                       {{/if}}
-                                       {{if !$is_default}}
-                                       <li role="presentation" class="divider"></li>
-                                       <li role="presentation"><a role="menuitem" href="{{$profile_drop_link}}" id="profile-edit-drop-link" title="{{$del_prof}}"><i class="fa fa-trash" aria-hidden="true"></i>&nbsp;{{$del_prof}}</a></li>
-                                       {{/if}}
-                               </ul>
-                       </li>
-
-               </ul>
-       </div>
-
-       <div id="profile-edit-links-end"></div>
-
-       <form enctype="multipart/form-data" action="profile_photo" method="post">
-               <input type='hidden' name='form_security_token' value='{{$form_security_token_photo}}'>
-               <input type="hidden" name="profile" value="{{$profile_name.2}}" />
-
-               <div id="profile-photo-upload-section" class="panel">
-                       <a id="profile-photo-upload-close" class="close pull-right" onclick="openClose('profile-photo-upload-section');"><i class="fa fa-times" aria-hidden="true"></i></a>
-                       <div id="profile-photo-upload-wrapper">
-                               <label id="profile-photo-upload-label" for="profile-photo-upload">{{$lbl_profile_photo}}:</label>
-                               <input name="userfile" type="file" id="profile-photo-upload" size="48" />
-                       </div>
-
-                       <div class="profile-edit-submit-wrapper pull-right" >
-                               <button type="submit" name="submit" class="profile-edit-submit-butto btn btn-primary" value="{{$submit}}">{{$submit}}</button>
-                       </div>
-                       <div class="clear"></div>
-               </div>
-       </form>
-
-       {{* Most of the Variables used below are arrays in the following style
-               0 => Some kind of identifier (e.g. for the ID)
-               1 => The label description
-               2 => The input values
-               3 => The additional help text (if available)
-       *}}
-
-       <form id="profile-edit-form" name="form1" action="profiles/{{$profile_id}}" method="post" >
-               <input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
-
-               {{* Some hints to characteristics of the current profile (if available) *}}
-               {{if $is_default}}
-               <div class="section-content-info-wrapper">{{$default nofilter}}</div>
-               {{/if}}
-
-               {{* friendica differs in $detailled_profile (all fields available and a short Version if this is variable false *}}
-               {{if $detailled_profile}}
-               <div class="panel-group panel-group-settings" id="profile-edit-wrapper" role="tablist" aria-multiselectable="true">
-                       {{* The personal settings *}}
-                       <div class="panel">
-                               <div class="section-subtitle-wrapper" role="tab" id="personal">
-                                       <h4>
-                                               <a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#personal-collapse" aria-expanded="true" aria-controls="personal-collapse">
-                                                       {{$lbl_personal_section}}
-                                               </a>
-                                       </h4>
-                               </div>
-                               {{* for the $detailled_profile we use bootstraps collapsable panel-groups to have expandable groups *}}
-                               <div id="personal-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="personal">
-                                       <div class="section-content-tools-wrapper">
-                                               {{include file="field_yesno.tpl" field=$details}}
-
-                                               {{include file="field_input.tpl" field=$profile_name}}
-
-                                               {{include file="field_input.tpl" field=$name}}
-
-                                               {{include file="field_input.tpl" field=$pdesc}}
-
-                                               <div id="profile-edit-gender-wrapper" class="form-group field select">
-                                                       <label id="profile-edit-gender-label" for="gender-select" >{{$lbl_gender}} </label>
-                                                       {{$gender nofilter}}
-                                               </div>
-                                               <div class="clear"></div>
-
-                                               {{$dob nofilter}}
-
-                                               {{$hide_friends nofilter}}
-
-                                               <div class="form-group pull-right" >
-                                                       <button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
-                                               </div>
-                                               <div class="clear"></div>
-                                       </div>
-                               </div>
-                       </div>
-
-                       {{* The location settings *}}
-                       <div class="panel">
-                               <div class="section-subtitle-wrapper" role="tab" id="location">
-                                       <h4>
-                                               <a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#location-collapse" aria-expanded="false" aria-controls="location-collapse">
-                                                       {{$lbl_location_section}}
-                                               </a>
-                                       </h4>
-                               </div>
-                               <div id="location-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="location">
-                                       <div class="section-content-tools-wrapper">
-                                               {{include file="field_input.tpl" field=$address}}
-
-                                               {{include file="field_input.tpl" field=$locality}}
-
-
-                                               {{include file="field_input.tpl" field=$postal_code}}
-
-                                               <div id="profile-edit-country-name-wrapper" class="form-group field select">
-                                                       <label id="profile-edit-country-name-label" for="profile-edit-country-name" >{{$country_name.1}} </label>
-                                                       <select name="country_name" id="profile-edit-country-name" class="form-control" onChange="Fill_States('{{$region.2}}');">
-                                                               <option selected="selected" >{{$country_name.2}}</option>
-                                                               <option>temp</option>
-                                                       </select>
-                                               </div>
-                                               <div class="clear"></div>
-
-                                               <div id="profile-edit-region-wrapper" class="form-group field select">
-                                                       <label id="profile-edit-region-label" for="profile-edit-region" >{{$region.1}} </label>
-                                                       <select name="region" id="profile-edit-region" class="form-control" onChange="Update_Globals();" >
-                                                               <option selected="selected" >{{$region.2}}</option>
-                                                               <option>temp</option>
-                                                       </select>
-                                               </div>
-                                               <div class="clear"></div>
-
-                                               {{include file="field_input.tpl" field=$hometown}}
-
-                                               <div class="form-group pull-right" >
-                                                       <button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
-                                               </div>
-                                               <div class="clear"></div>
-                                       </div>
-                               </div>
-                       </div>
-
-                       {{* The settings for relations *}}
-                       <div class="panel">
-                               <div class="section-subtitle-wrapper" role="tab" id="relation">
-                                       <h4>
-                                               <a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#relation-collapse" aria-expanded="false" aria-controls="relation-collapse">
-                                                       {{$lbl_relation_section}}
-                                               </a>
-                                       </h4>
-                               </div>
-                               <div id="relation-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="relation">
-                                       <div class="section-content-tools-wrapper">
-                                               <div id="profile-edit-marital-wrapper" class="form-group field select" >
-                                                               <label id="profile-edit-marital-label" for="profile-edit-marital" >{{$lbl_marital nofilter}}</label>
-                                                               {{$marital.selector nofilter}}
-                                               </div>
-                                               <div class="clear"></div>
-
-                                               {{include file="field_input.tpl" field=$with}}
-
-                                               {{include file="field_input.tpl" field=$howlong}}
-
-                                               <div id="profile-edit-sexual-wrapper" class="form-group field select" >
-                                                       <label id="profile-edit-sexual-label" for="sexual-select" >{{$lbl_sexual}}</label>
-                                                       {{$sexual.selector nofilter}}
-                                               </div>
-                                               <div class="clear"></div>
-
-                                               <div class="form-group pull-right" >
-                                                       <button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
-                                               </div>
-                                               <div class="clear"></div>
-                                       </div>
-                               </div>
-                       </div>
-
-                       {{* The miscellanous other settings *}}
-                       <div class="panel">
-                               <div class="section-subtitle-wrapper" role="tab" id="miscellaneous">
-                                       <h4>
-                                               <a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#miscellaneous-collapse" aria-expanded="false" aria-controls="miscellaneous-collapse">
-                                                       {{$lbl_miscellaneous_section}}
-                                               </a>
-                                       </h4>
-                               </div>
-                               <div id="miscellaneous-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="miscellaneous">
-                                       <div class="section-content-tools-wrapper">
-                                               {{include file="field_input.tpl" field=$homepage}}
-
-                                               {{include file="field_input.tpl" field=$xmpp}}
-
-                                               {{include file="field_input.tpl" field=$pub_keywords}}
-
-                                               {{include file="field_input.tpl" field=$prv_keywords}}
-
-                                               {{include file="field_input.tpl" field=$politic}}
-
-                                               {{include file="field_input.tpl" field=$religion}}
-
-
-                                               {{include file="field_textarea.tpl" field=$about}}
-
-                                               {{include file="field_textarea.tpl" field=$contact}}
-
-                                               {{include file="field_textarea.tpl" field=$interest}}
-
-                                               {{include file="field_textarea.tpl" field=$likes}}
-
-                                               {{include file="field_textarea.tpl" field=$dislikes}}
-
-                                               {{include file="field_textarea.tpl" field=$music}}
-
-                                               {{include file="field_textarea.tpl" field=$book}}
-
-                                               {{include file="field_textarea.tpl" field=$tv}}
-
-                                               {{include file="field_textarea.tpl" field=$film}}
-
-                                               {{include file="field_textarea.tpl" field=$romance}}
-
-                                               {{include file="field_textarea.tpl" field=$work}}
-
-                                               {{include file="field_textarea.tpl" field=$education}}
-
-                                               <div class="form-group pull-right" >
-                                                       <button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
-                                               </div>
-                                               <div class="clear"></div>
-                                       </div>
-                               </div>
-                       </div>
-               </div>
-
-               {{else}}
-               {{* if $detailled_profile not available a short version of the setting page is displayed *}}
-               {{if $personal_account}}
-               {{include file="field_yesno.tpl" field=$details}}
-               {{/if}}
-
-               {{include file="field_input.tpl" field=$profile_name}}
-
-               {{include file="field_input.tpl" field=$name}}
-
-               {{if $personal_account}}
-               <div id="profile-edit-gender-wrapper" class="form-group field select">
-                       <label id="profile-edit-gender-label" for="gender-select" >{{$lbl_gender}} </label>
-                       {{$gender nofilter}}
-               </div>
-               <div class="clear"></div>
-
-               {{$dob nofilter}}
-
-               {{/if}}
-
-               {{include file="field_input.tpl" field=$homepage}}
-
-               {{include file="field_input.tpl" field=$xmpp}}
-
-               {{$hide_friends nofilter}}
-
-               {{include file="field_input.tpl" field=$address}}
-
-               {{include file="field_input.tpl" field=$locality}}
-
-
-               {{include file="field_input.tpl" field=$postal_code}}
-
-               <div id="profile-edit-country-name-wrapper" class="form-group field select">
-                       <label id="profile-edit-country-name-label" for="profile-edit-country-name" >{{$country_name.1}} </label>
-                       <select name="country_name" id="profile-edit-country-name" class="form-control" onChange="Fill_States('{{$region.2}}');">
-                               <option selected="selected" >{{$country_name.2}}</option>
-                               <option>temp</option>
-                       </select>
-               </div>
-               <div class="clear"></div>
-
-               <div id="profile-edit-region-wrapper" class="form-group field select">
-                       <label id="profile-edit-region-label" for="profile-edit-region" >{{$region.1}} </label>
-                       <select name="region" id="profile-edit-region" class="form-control" onChange="Update_Globals();" >
-                               <option selected="selected" >{{$region.2}}</option>
-                               <option>temp</option>
-                       </select>
-               </div>
-               <div class="clear"></div>
-
-               {{include file="field_input.tpl" field=$pub_keywords}}
-
-               {{include file="field_input.tpl" field=$prv_keywords}}
-
-               {{include file="field_textarea.tpl" field=$about}}
-
-               <div class="form-group pull-right" >
-                       <button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
-               </div>
-               <div class="clear"></div>
-
-               <input type="hidden" name="pdesc" id="profile-edit-pdesc" value="{{$pdesc.2}}" />
-               <input type="hidden" id="contact-jot-text" name="contact" value="{{$contact.2}}" />
-               <input type="hidden" name="hometown" id="profile-edit-hometown" value="{{$hometown.2}}" />
-               <input type="hidden" name="politic" id="profile-edit-politic" value="{{$politic.2}}" />
-               <input type="hidden" name="religion" id="profile-edit-religion" value="{{$religion.2}}" />
-               <input type="hidden" id="likes-jot-text" name="likes" value="{{$likes.2}}" />
-               <input type="hidden" id="dislikes-jot-text" name="dislikes" value="{{$dislikes.2}}" />
-               <input type="hidden" name="marital" id="profile-edit-marital" value="{{$marital.value}}" />
-               <input type="hidden" name="with" id="profile-edit-with" value="{{$with.2}}" />
-               <input type="hidden" name="howlong" id="profile-edit-howlong" value="{{$howlong.2}}" />
-               <input type="hidden" name="sexual" id="profile-edit-sexual" value="{{$sexual.value}}" />
-               <input type="hidden" id="romance-jot-text" name="romance" value="{{$romance.2}}" />
-               <input type="hidden" id="work-jot-text" name="work" value="{{$work.2}}" />
-               <input type="hidden" id="education-jot-text" name="education" value="{{$education.2}}" />
-               <input type="hidden" id="interest-jot-text" name="interest" value="{{$interest.2}}" />
-               <input type="hidden" id="music-jot-text" name="music" value="{{$music.2}}" />
-               <input type="hidden" id="book-jot-text" name="book" value="{{$book.2}}" />
-               <input type="hidden" id="tv-jot-text" name="tv" value="{{$tv.2}}" />
-               <input type="hidden" id="film-jot-text" name="film" value="{{$film.2}}" />
-
-               {{/if}}
-       </form>
-</div>
-
-<script type="text/javascript">
-       Fill_Country('{{$country_name.2}}');
-       Fill_States('{{$region.2}}');
-
-       // initiale autosize for the textareas
-       autosize($("textarea.text-autosize"));
-</script>
diff --git a/view/theme/frio/templates/profile_entry.tpl b/view/theme/frio/templates/profile_entry.tpl
deleted file mode 100644 (file)
index ba8f547..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-
-<div class="profile-listing-row" >
-       <div class="profile-listing-cell" >
-               <a href="profiles/{{$id}}" class="profile-listing-edit-link"><img class="profile-listing-photo" id="profile-listing-photo-{{$id}}" src="{{$photo}}" alt="{{$alt}}" /></a>
-       </div>
-       <div class="profile-listing-photo-end"></div>
-       <div class="profile-listing-cell" id="profile-listing-name-{{$id}}">
-               <a href="profiles/{{$id}}" class="profile-listing-edit-link" >{{$profile_name}}</a>
-       </div>
-       <div class="profile-listing-cell">
-               {{$visible nofilter}}
-       </div>
-</div>
-<div class="profile-listing-end"></div>
-
diff --git a/view/theme/frio/templates/profile_listing_header.tpl b/view/theme/frio/templates/profile_listing_header.tpl
deleted file mode 100644 (file)
index 3419c41..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-
-<div class="generic-page-wrapper">
-       <div class="section-title-wrapper pull-left">
-               <h2>{{$header}}</h2>
-       </div>
-       <div id="profile-listing-new-link-wrapper" class="pull-right" >
-               <a href="{{$cr_new_link}}" id="profile-listing-new-link" class="page-action faded-icon" title="{{$cr_new}}" data-toggle="tooltip">
-               <i class="fa fa-plus"></i></a>
-       </div>
-
-       <div class="section-content-wrapper">
-               <div id="profile-listing-profiles" class="profile-listing-table">
-                       {{$profiles nofilter}}
-               </div>
-       </div>
-</div>
diff --git a/view/theme/frio/templates/settings/profile/field/edit.tpl b/view/theme/frio/templates/settings/profile/field/edit.tpl
new file mode 100644 (file)
index 0000000..f28e559
--- /dev/null
@@ -0,0 +1,29 @@
+<fieldset data-id="{{$profile_field.id}}">
+       <legend>&#8801; {{$profile_field.legend}}</legend>
+
+       <input type="hidden" name="profile_field_order[]" value="{{$profile_field.id}}">
+
+       {{include file="field_input.tpl" field=$profile_field.fields.label}}
+
+       {{include file="field_textarea.tpl" field=$profile_field.fields.value}}
+
+       {{* Block for setting default permissions *}}
+       <p>
+               <a id="settings-default-perms-menu" class="settings-default-perms" data-toggle="modal" data-target="#profile-field-acl-{{$profile_field.id}}">{{$profile_field.permissions}} {{$profile_field.permdesc}}</a>
+       </p>
+
+       {{* We include the aclModal directly into the template since we cant use frio's default modal *}}
+       <div class="modal" id="profile-field-acl-{{$profile_field.id}}">
+               <div class="modal-dialog">
+                       <div class="modal-content">
+                               <div class="modal-header">
+                                       <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+                                       <h4 class="modal-title">{{$profile_field.permissions}}</h4>
+                               </div>
+                               <div class="modal-body">
+                                       {{$profile_field.fields.acl nofilter}}
+                               </div>
+                       </div>
+               </div>
+       </div>
+</fieldset>
\ No newline at end of file
diff --git a/view/theme/frio/templates/settings/profile/index.tpl b/view/theme/frio/templates/settings/profile/index.tpl
new file mode 100644 (file)
index 0000000..4d7cf8d
--- /dev/null
@@ -0,0 +1,184 @@
+<div class="generic-page-wrapper">
+       {{include file="section_title.tpl" title=$banner}}
+
+       {{* The actions dropdown which can performed to the current profile *}}
+       <div id="profile-edit-links">
+               <ul class="nav nav-pills preferences">
+                       <li class="dropdown pull-right">
+                               <button type="button" class="btn btn-link btn-sm dropdown-toggle" id="profile-edit-links-dropdown" data-toggle="dropdown" aria-expanded="false">
+                                       <i class="fa fa-angle-down" aria-hidden="true"></i>&nbsp;{{$profile_action}}
+                               </button>
+                               <ul class="dropdown-menu pull-right" role="menu" aria-labelledby="profile-edit-links-dropdown">
+                                       <li role="presentation"><a role="menuitem" href="{{$profpiclink}}" id="profile-photo_upload-link" title="{{$profpic}}"><i class="fa fa-user" aria-hidden="true"></i>&nbsp;{{$profpic}}</a></li>
+                                       <li role="presentation"><button role="menuitem" type="button" class="btn-link" id="profile-photo_upload-link-new" title="{{$lbl_profile_photo}}" onclick="openClose('profile-photo-upload-section');"><i class="fa fa-user" aria-hidden="true"></i>&nbsp;{{$lbl_profile_photo}}</button></li>
+                                       <li role="presentation" class="divider"></li>
+                                       <li role="presentation"><a role="menuitem" href="profile/{{$nickname}}" id="profile-edit-view-link" title="{{$viewprof}}">{{$viewprof}}</a></li>
+                               </ul>
+                       </li>
+               </ul>
+       </div>
+
+       <div id="profile-edit-links-end"></div>
+
+       <form enctype="multipart/form-data" action="settings/profile/photo" method="post">
+               <input type="hidden" name="form_security_token" value="{{$form_security_token_photo}}">
+
+               <div id="profile-photo-upload-section" class="panel">
+                       <a id="profile-photo-upload-close" class="close pull-right" onclick="openClose('profile-photo-upload-section');"><i class="fa fa-times" aria-hidden="true"></i></a>
+                       <div id="profile-photo-upload-wrapper">
+                               <label id="profile-photo-upload-label" for="profile-photo-upload">{{$lbl_profile_photo}}:</label>
+                               <input name="userfile" type="file" id="profile-photo-upload" size="48" />
+                       </div>
+
+                       <div class="profile-edit-submit-wrapper pull-right">
+                               <button type="submit" name="submit" class="profile-edit-submit-button btn btn-primary" value="{{$submit}}">{{$submit}}</button>
+                       </div>
+                       <div class="clear"></div>
+               </div>
+       </form>
+
+       {{* Most of the Variables used below are arrays in the following style
+               0 => Some kind of identifier (e.g. for the ID)
+               1 => The label description
+               2 => The input values
+               3 => The additional help text (if available)
+       *}}
+
+       <form id="profile-edit-form" name="form1" action="" method="post">
+               <input type="hidden" name="form_security_token" value="{{$form_security_token}}">
+
+               <div class="panel-group panel-group-settings" id="profile-edit-wrapper" role="tablist" aria-multiselectable="true">
+                       {{* The personal settings *}}
+                       <div class="panel">
+                               <div class="section-subtitle-wrapper" role="tab" id="personal">
+                                       <h4>
+                                               <a class="accordion-toggle" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#personal-collapse" aria-expanded="true" aria-controls="personal-collapse">
+                                                       {{$lbl_personal_section}}
+                                               </a>
+                                       </h4>
+                               </div>
+                               {{* for the $detailed_profile we use bootstraps collapsable panel-groups to have expandable groups *}}
+                               <div id="personal-collapse" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="personal">
+                                       <div class="section-content-tools-wrapper">
+                                               {{include file="field_input.tpl" field=$name}}
+
+                                               {{include file="field_input.tpl" field=$pdesc}}
+
+                                               {{$dob nofilter}}
+
+                                               {{$hide_friends nofilter}}
+
+                                               <div class="form-group pull-right">
+                                                       <button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
+                                               </div>
+                                               <div class="clear"></div>
+                                       </div>
+                               </div>
+                       </div>
+
+                       {{* The location settings *}}
+                       <div class="panel">
+                               <div class="section-subtitle-wrapper" role="tab" id="location">
+                                       <h4>
+                                               <a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#location-collapse" aria-expanded="false" aria-controls="location-collapse">
+                                                       {{$lbl_location_section}}
+                                               </a>
+                                       </h4>
+                               </div>
+                               <div id="location-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="location">
+                                       <div class="section-content-tools-wrapper">
+                                               {{include file="field_input.tpl" field=$address}}
+
+                                               {{include file="field_input.tpl" field=$locality}}
+
+                                               {{include file="field_input.tpl" field=$postal_code}}
+
+                                               <div id="profile-edit-country-name-wrapper" class="form-group field select">
+                                                       <label id="profile-edit-country-name-label" for="profile-edit-country-name">{{$country_name.1}} </label>
+                                                       <select name="country_name" id="profile-edit-country-name" class="form-control" onChange="Fill_States('{{$region.2}}');">
+                                                               <option selected="selected">{{$country_name.2}}</option>
+                                                               <option>temp</option>
+                                                       </select>
+                                               </div>
+                                               <div class="clear"></div>
+
+                                               <div id="profile-edit-region-wrapper" class="form-group field select">
+                                                       <label id="profile-edit-region-label" for="profile-edit-region">{{$region.1}} </label>
+                                                       <select name="region" id="profile-edit-region" class="form-control" onChange="Update_Globals();">
+                                                               <option selected="selected">{{$region.2}}</option>
+                                                               <option>temp</option>
+                                                       </select>
+                                               </div>
+                                               <div class="clear"></div>
+
+                                               <div class="form-group pull-right">
+                                                       <button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
+                                               </div>
+                                               <div class="clear"></div>
+                                       </div>
+                               </div>
+                       </div>
+
+                       {{* The miscellanous other settings *}}
+                       <div class="panel">
+                               <div class="section-subtitle-wrapper" role="tab" id="miscellaneous">
+                                       <h4>
+                                               <a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#miscellaneous-collapse" aria-expanded="false" aria-controls="miscellaneous-collapse">
+                                                       {{$lbl_miscellaneous_section}}
+                                               </a>
+                                       </h4>
+                               </div>
+                               <div id="miscellaneous-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="miscellaneous">
+                                       <div class="section-content-tools-wrapper">
+                                               {{include file="field_input.tpl" field=$homepage}}
+
+                                               {{include file="field_input.tpl" field=$xmpp}}
+
+                                               {{include file="field_input.tpl" field=$pub_keywords}}
+
+                                               {{include file="field_input.tpl" field=$prv_keywords}}
+
+                                               <div class="form-group pull-right">
+                                                       <button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
+                                               </div>
+                                               <div class="clear"></div>
+                                       </div>
+                               </div>
+                       </div>
+
+                       {{* The miscellanous other settings *}}
+                       <div class="panel">
+                               <div class="section-subtitle-wrapper" role="tab" id="custom-fields">
+                                       <h4>
+                                               <a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#custom-fields-collapse" aria-expanded="false" aria-controls="custom-fields-collapse">
+                                                       {{$lbl_custom_fields_section}}
+                                               </a>
+                                       </h4>
+                               </div>
+                               <div id="custom-fields-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="custom-fields">
+                                       <div class="section-content-tools-wrapper">
+                                               {{$custom_fields_description nofilter}}
+                                               <div id="profile-custom-fields">
+                                               {{foreach $custom_fields as $custom_field}}
+                                                       {{include file="settings/profile/field/edit.tpl" profile_field=$custom_field}}
+                                               {{/foreach}}
+                                               </div>
+
+                                               <div class="form-group pull-right">
+                                                       <button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
+                                               </div>
+                                               <div class="clear"></div>
+                                       </div>
+                               </div>
+                       </div>
+               </div>
+       </form>
+</div>
+
+<script type="text/javascript">
+       Fill_Country('{{$country_name.2}}');
+       Fill_States('{{$region.2}}');
+
+       // initiale autosize for the textareas
+       autosize($("textarea.text-autosize"));
+</script>
index 4ed94b182736603c035b750546abf440867f2952..0a695191f03dd4a87c22cfe89cf653c63bfd6f6e 100644 (file)
                                        <div class="section-content-tools-wrapper">
                                                <div id="settings-notifications">
 
-                                                       <div id="settings-notify-desc"><h4>{{$lbl_not}}</h4></div>
+                                                       <div id="settings-notification-desc"><h4>{{$lbl_not}}</h4></div>
 
                                                        <div class="group">
                                                                {{include file="field_intcheckbox.tpl" field=$notify1}}
diff --git a/view/theme/frio/templates/suggestions.tpl b/view/theme/frio/templates/suggestions.tpl
deleted file mode 100644 (file)
index e2399eb..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-{{include file="intros.tpl"}}
\ No newline at end of file
index 94955581d1dc2497f46b6fefe58ad8b7acf5ac3c..3e8a2faea737bea616a4baa1bf11fcfc7f516ab2 100644 (file)
@@ -236,7 +236,11 @@ as the value of $top_child_total (this is done at the end of this file)
                                                {{if $item.owner_self}}
                                                        {{include file="sub/delivery_count.tpl" delivery=$item.delivery}}
                                                {{/if}}
-                                               <span class="pinned">{{$item.pinned}}</span>
+                                               {{if $item.pinned}}
+                                                       &bull; <i class="fa fa-thumb-tack" aria-hidden="true" title="{{$item.pinned}}"></i>
+                                                       <span class="sr-only">{{$item.pinned}}</span>
+                                               {{/if}}
+
                                        </small>
                                </div>
 
index 0ce009cdb72cc9a8614bed31c46b6654b312b81e..64e4840e86031bd8e126f2422b816474cd2a9c60 100644 (file)
@@ -627,7 +627,7 @@ nav .nav-menu-icon img {
   width: 22px;
   height: 22px;
 }
-nav .nav-menu-icon .nav-notify {
+nav .nav-menu-icon .nav-notification {
   top: 3px;
 }
 nav .nav-menu {
@@ -641,7 +641,7 @@ nav .nav-menu {
 nav .nav-menu.selected {
   border-bottom: 3px solid #9eabb0;
 }
-nav .nav-notify {
+nav .nav-notification {
   display: none;
   position: absolute;
   background-color: #19aeff;
@@ -655,7 +655,7 @@ nav .nav-notify {
   min-width: 15px;
   text-align: right;
 }
-nav .nav-notify.show {
+nav .nav-notification.show {
   display: block;
 }
 nav #nav-help-link,
@@ -1964,6 +1964,9 @@ ul.tabs li .active {
   list-style: none;
   margin-top: 10px;
 }
+#profile-menu {
+       display: none;
+}
 #profile-edit-default-desc {
   color: #FF0000;
   border: 1px solid #FF8888;
index c0a1befad9a9995afec2539f40eb2c8259d7749b..40a0c71617cee22a7fd10e81e82932a130685ae0 100644 (file)
@@ -627,7 +627,7 @@ nav .nav-menu-icon img {
   width: 22px;
   height: 22px;
 }
-nav .nav-menu-icon .nav-notify {
+nav .nav-menu-icon .nav-notification {
   top: 3px;
 }
 nav .nav-menu {
@@ -641,7 +641,7 @@ nav .nav-menu {
 nav .nav-menu.selected {
   border-bottom: 3px solid #9eabb0;
 }
-nav .nav-notify {
+nav .nav-notification {
   display: none;
   position: absolute;
   background-color: #dc0000;
@@ -655,7 +655,7 @@ nav .nav-notify {
   min-width: 15px;
   text-align: right;
 }
-nav .nav-notify.show {
+nav .nav-notification.show {
   display: block;
 }
 nav #nav-help-link,
@@ -1964,6 +1964,9 @@ ul.tabs li .active {
   list-style: none;
   margin-top: 10px;
 }
+#profile-menu {
+       display: none;
+}
 #profile-edit-default-desc {
   color: #FF0000;
   border: 1px solid #FF8888;
index 05cb05b1869327bb940ec6a8db1853d3ad612227..16887f1e6a16c1edcc40a66b9aa5db254830494b 100644 (file)
@@ -627,7 +627,7 @@ nav .nav-menu-icon img {
   width: 22px;
   height: 22px;
 }
-nav .nav-menu-icon .nav-notify {
+nav .nav-menu-icon .nav-notification {
   top: 3px;
 }
 nav .nav-menu {
@@ -641,7 +641,7 @@ nav .nav-menu {
 nav .nav-menu.selected {
   border-bottom: 3px solid #9eabb0;
 }
-nav .nav-notify {
+nav .nav-notification {
   display: none;
   position: absolute;
   background-color: #86608e;
@@ -655,7 +655,7 @@ nav .nav-notify {
   min-width: 15px;
   text-align: right;
 }
-nav .nav-notify.show {
+nav .nav-notification.show {
   display: block;
 }
 nav #nav-help-link,
@@ -1964,6 +1964,9 @@ ul.tabs li .active {
   list-style: none;
   margin-top: 10px;
 }
+#profile-menu {
+       display: none;
+}
 #profile-edit-default-desc {
   color: #FF0000;
   border: 1px solid #FF8888;
index 2406fea538a0541f28bf8ff9f144b7e43fa2e021..ce5c038d7d54bab74408dbb7f779c36e8697abe7 100644 (file)
@@ -180,7 +180,7 @@ nav {
                        }
 
                                img { width: 22px; height: 22px; }
-                               .nav-notify { top: 3px; }
+                               .nav-notification { top: 3px; }
                }
 
                .nav-menu {
@@ -196,7 +196,7 @@ nav {
 
                }
 
-               .nav-notify {
+               .nav-notification {
                        display: none;
                        position: absolute;
                        background-color: @NavbarNotifBg;
@@ -1257,6 +1257,10 @@ ul.tabs {
         margin-top: 10px;
 }
 
+#profile-menu {
+       display: none;
+}
+
 #profile-edit-default-desc {
        color: #FF0000;
        border: 1px solid #FF8888;
index c42e570f5dfe08850ce61d6a2f68250f630da248..13b3aa1d30087b09003fc082cf985e3316e9b30c 100644 (file)
                {{if $nav.network}}
                        <li id="nav-network-link" class="nav-menu {{$sel.network}}">
                                <a accesskey="n" class="{{$nav.network.2}}" href="{{$nav.network.0}}" title="{{$nav.network.3}}" >{{$nav.network.1}}</a>
-                               <span id="net-update" class="nav-notify"></span>
+                               <span id="net-update" class="nav-notification"></span>
                        </li>
                {{/if}}
 
                {{if $nav.home}}
                        <li id="nav-home-link" class="nav-menu {{$sel.home}}">
                                <a accesskey="p" class="{{$nav.home.2}}" href="{{$nav.home.0}}" title="{{$nav.home.3}}" >{{$nav.home.1}}</a>
-                               <span id="home-update" class="nav-notify"></span>
+                               <span id="home-update" class="nav-notification"></span>
                        </li>
                {{/if}}
 
@@ -45,7 +45,7 @@
                                <a class="{{$nav.introductions.2}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >
                                    <span class="icon s22 intro">{{$nav.introductions.1}}</a>
                                </a>
-                               <span id="intro-update" class="nav-notify"></span>
+                               <span id="intro-update" class="nav-notification"></span>
                        </li>
                {{/if}}
 
                                <a class="{{$nav.messages.2}}" href="{{$nav.messages.0}}" title="{{$nav.messages.3}}" >
                                    <span class="icon s22 mail">{{$nav.messages.1}}</a>
                                </a>
-                               <span id="mail-update" class="nav-notify"></span>
+                               <span id="mail-update" class="nav-notification"></span>
                        </li>
                {{/if}}
 
                {{if $nav.notifications}}
                        <li  id="nav-notifications-linkmenu" class="nav-menu-icon"><a accesskey="f" href="{{$nav.notifications.0}}" rel="#nav-notifications-menu" title="{{$nav.notifications.1}}"><span class="icon s22 notify">{{$nav.notifications.1}}</span></a>
-                               <span id="notify-update" class="nav-notify"></span>
+                               <span id="notification-update" class="nav-notification"></span>
                                <ul id="nav-notifications-menu" class="menu-popup">
                                        <!-- TODO: better icons! -->
-                                       <li id="nav-notifications-mark-all" class="toolbar"><a href="#" onclick="notifyMarkAll(); return false;" title="{{$nav.notifications.mark.3}}"><span class="icon s10 edit"></span></a></a><a href="{{$nav.notifications.all.0}}" title="{{$nav.notifications.all.1}}"><span class="icon s10 plugin"></span></a></li>
+                                       <li id="nav-notifications-mark-all" class="toolbar"><a href="#" onclick="notificationMarkAll(); return false;" title="{{$nav.notifications.mark.3}}"><span class="icon s10 edit"></span></a></a><a href="{{$nav.notifications.all.0}}" title="{{$nav.notifications.all.1}}"><span class="icon s10 plugin"></span></a></li>
                                        <li class="empty">{{$emptynotifications}}</li>
                                </ul>
                        </li>
index 7e276f459753802ab1168a480c6e13e5c5dc86d8..52324c0a9756264f1b015e0525c7520510cb9cec 100644 (file)
@@ -104,6 +104,14 @@ input[type=submit]:active {
        top: 1px;
 }
 
+.btn {
+       background-color: transparent;
+       box-shadow: none;
+       border: none;
+       padding: 0;
+       text-align: inherit;
+}
+
 #search-text,
 #search-submit,
 #search-save {
@@ -616,7 +624,7 @@ ul#user-menu-popup li a.nav-sep {
        padding-left: 11px;
 }
 
-#notify-update {
+#notification-update {
        background-position: 0px -168px;
 }
 
@@ -2127,6 +2135,10 @@ div[id$="wrapper"] br {
        position: absolute;
 }
 
+#profile-menu {
+       display: none;
+}
+
 #cropimage-wrapper {
        float:left;
 }
@@ -4211,7 +4223,7 @@ a.active {
        margin-right: -20px;
 }
 
-.nav-notify {
+.nav-notification {
        display: none;
        position: absolute;
        font-size: 10px;
@@ -4221,7 +4233,7 @@ a.active {
        min-width: 15px;
        text-align: right;
 }
-.nav-notify.show {
+.nav-notification.show {
        display: block;
 }
 #nav-notifications-menu {
@@ -4353,11 +4365,11 @@ a.active {
        filter: alpha(opacity=100);
 }
 
-.notify-seen {
+.notification-seen {
        background: #000000;
 }
 
-.notify-seen a {
+.notification-seen a {
        color: #efefef !important;
 }
 
@@ -4604,7 +4616,7 @@ div #datebrowse-sidebar.widget {
 }
 
 #settings-activity-desc,
-#settings-notify-desc {
+#settings-notification-desc {
        margin: 10px 10px 10px 0;
        font-weight: bold;
 }
index a5c16d23f365de92386c9af87922402683ee8c4b..5ce1eb3bb757384c5535d817f29f93a6612c25bd 100644 (file)
@@ -8,10 +8,10 @@
 <!--           {{if $nav.notifications}}<a id="intro-update" class="nav-ajax-update" href="{{$nav.notifications.0}}" title="{{$nav.notifications.1}}"></a>{{/if}} -->
                {{if $nav.introductions}}<a id="intro-update" class="nav-ajax-update" href="{{$nav.introductions.0}}" title="{{$nav.introductions.1}}"></a>{{/if}}
                {{if $nav.messages}}<a id="mail-update" class="nav-ajax-update" href="{{$nav.messages.0}}" title="{{$nav.messages.1}}"></a>{{/if}}
-               {{if $nav.notifications}}<a rel="#nav-notifications-menu" id="notify-update" class="nav-ajax-update" href="{{$nav.notifications.0}}"  title="{{$nav.notifications.1}}"></a>{{/if}}
+               {{if $nav.notifications}}<a rel="#nav-notifications-menu" id="notification-update" class="nav-ajax-update" href="{{$nav.notifications.0}}"  title="{{$nav.notifications.1}}"></a>{{/if}}
 
                <ul id="nav-notifications-menu" class="menu-popup">
-                       <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
+                       <li id="nav-notifications-mark-all"><a href="#" onclick="notificationMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
                        <li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
                        <li class="empty">{{$emptynotifications}}</li>
                </ul>
@@ -38,7 +38,7 @@
                        <li><a id="nav-directory-link" class="nav-link {{$nav.directory.2}}" href="{{$nav.directory.0}}">{{$nav.directory.1}}</a></li>
                        {{if $nav.apps}}<li><a id="nav-apps-link" class="nav-link {{$nav.apps.2}}" href="{{$nav.apps.0}}">{{$nav.apps.1}}</a></li>{{/if}}
                        
-                       {{if $nav.notifications}}<li><a id="nav-notify-link" class="nav-commlink nav-sep {{$nav.notifications.2}}" href="{{$nav.notifications.0}}">{{$nav.notifications.1}}</a></li>{{/if}}
+                       {{if $nav.notifications}}<li><a id="nav-notification-link" class="nav-commlink nav-sep {{$nav.notifications.2}}" href="{{$nav.notifications.0}}">{{$nav.notifications.1}}</a></li>{{/if}}
                        {{if $nav.messages}}<li><a id="nav-messages-link" class="nav-commlink {{$nav.messages.2}}" href="{{$nav.messages.0}}">{{$nav.messages.1}}</a></li>{{/if}}
                        {{if $nav.contacts}}<li><a id="nav-contacts-link" class="nav-commlink {{$nav.contacts.2}}" href="{{$nav.contacts.0}}">{{$nav.contacts.1}}</a></li>{{/if}}
                
index f18076b5071f95ed9e647ce10d594e2992fa3b55..ba48bc610654ca2cb2384b1afb597700a4b91f42 100644 (file)
@@ -29,7 +29,7 @@ nav {
        background-color: #1C2126 !important; 
 }
 
-nav .nav-notify {
+nav .nav-notification {
        background-color: #2C77AE !important
 }
 
@@ -89,11 +89,11 @@ table.smiley-preview{
 }
 
 /* Notifications */
-li.notify-unseen {
+li.notification-unseen {
        background-color: #252C33;
 }
 
-li.notify-seen {
+li.notification-seen {
        background-color: #1C2126;
 }
 
index 0bf29085315b13f78c6ff553f04655a585070f17..6f57f4fbe47408a55555728b726232cb58f72195 100644 (file)
@@ -23,7 +23,7 @@ nav a:hover,
   font: bold 11px/16px Arial;
 }
 
-nav .nav-notify {
+nav .nav-notification {
 /*  background-color: #427FED; */
   background-color: #CB4437;
   top: -3px;
@@ -33,7 +33,7 @@ nav .nav-notify {
   border-radius: 10px;
 }
 
-nav .nav-menu-icon .nav-notify {
+nav .nav-menu-icon .nav-notification {
   top: 0px;
 }
 
index 2be64ed4225582da73ab0bf3dd743d0f8e5015fc..7d9c09e3eeacdfc169fab5bcf8633c95293c3cb8 100644 (file)
@@ -60,7 +60,7 @@ nav a:hover,
   font: bold 11px/16px Arial;
 }
 
-nav .nav-notify {
+nav .nav-notification {
   background-color: #CB4437;
   top: -3px;
   right: -4px;
@@ -69,7 +69,7 @@ nav .nav-notify {
   border-radius: 10px;
 }
 
-nav .nav-menu-icon .nav-notify {
+nav .nav-menu-icon .nav-notification {
   top: 0px;
 }
 
index 918f880a80a235c657820d04b6a0dc52c4c2a58f..7ed15fc890d67580d6103eb65d63cbfde5da0255 100644 (file)
@@ -17,7 +17,7 @@ nav a:hover,
   color: #fff;
 }
 
-nav .nav-notify {
+nav .nav-notification {
   background-color: #F80;
   top: 0px;
   right: -5px;
@@ -25,7 +25,7 @@ nav .nav-notify {
   border-radius: 5px 5px 5px 5px;
 }
 
-nav .nav-menu-icon .nav-notify {
+nav .nav-menu-icon .nav-notification {
   top: 0px;
 }
 
index d9e1304a90728723af9a8e2df104a9cd5cca5d5d..f28f8b556f3e40647bd82736bbfba4a31ac9bc8b 100644 (file)
@@ -687,8 +687,8 @@ nav .nav-menu img {
        margin-right: 4px;
 }
 
-nav .nav-menu > a > .nav-notify,
-nav .nav-menu-icon > a > .nav-notify {
+nav .nav-menu > a > .nav-notification,
+nav .nav-menu-icon > a > .nav-notification {
        position: absolute;
        top: 3px;
        right: -5px;
@@ -741,7 +741,7 @@ nav .nav-menu:hover {
        margin-right: -20px;
 }
 
-nav .nav-notify {
+nav .nav-notification {
        display: none;
        background-color: #F80;
        -moz-border-radius: 5px 5px 5px 5px;
@@ -753,7 +753,7 @@ nav .nav-notify {
        text-align: center;
        color: white;
 }
-nav .nav-notify.show {
+nav .nav-notification.show {
        display: inline-block;
 }
 
@@ -845,9 +845,9 @@ nav #nav-user-linkmenu {
        padding: 5px 10px; */
 }
 
-.notify-unseen {background-color: #FFF; }
+.notification-unseen {background-color: #FFF; }
 
-.notify-seen {
+.notification-seen {
        background: none repeat scroll 0 0 #EEE;
 }
 
@@ -2406,6 +2406,10 @@ aside #id_password {
        list-style: none;
 }
 
+#profile-menu {
+       display: none;
+}
+
 .profile-edit-side-div {
 /*  display: none; */
        float: right;
@@ -3236,7 +3240,6 @@ img.photo-album-photo {
 }
 #profile-edit-wrapper .toggle-section-content {
        background:#ededed;
-       max-width:599px;
        padding:5px;
 }
 
index bd07f182130240f72ae896fd57185e555f8e1817..3eaf163fc6ca85bc1ba2972b955abc674792eae8 100644 (file)
                                </div>
                                <div id="contact-info-end"></div>
                                {{/if}}
-
-                               {{if $profile_select}}
-                                       <div id="contact-edit-profile-select-text">
-                                       <h4>{{$lbl_vis1}}</h4>
-                                       <p>{{$lbl_vis2}}</p> 
-                                       </div>
-                                       {{$profile_select nofilter}}
-                                       <div id="contact-edit-profile-select-end"></div>
-                               {{/if}}
                        </div>
                        <input class="contact-edit-submit" type="submit" name="submit" value="{{$submit}}" />
                        {{/if}}
index a10fd0ab3db22f54387603e6fb066ee858508279..7982d5efa4da29e41cb3392d70e1b5b8e0ffa621 100644 (file)
@@ -17,7 +17,7 @@
                                <a accesskey="p" class="{{$nav.home.2}}" href="{{$nav.home.0}}" title="{{$nav.home.3}}" >
                                        <span class="desktop-view">{{$nav.home.1}}</span>
                                        <i class="icon s22 icon-home mobile-view"><span class="sr-only">{{$nav.home.1}}</span></i>
-                                       <span id="home-update" class="nav-notify"></span>
+                                       <span id="home-update" class="nav-notification"></span>
                                </a>
                        </li>
                {{/if}}
@@ -26,7 +26,7 @@
                                <a accesskey="n" class="{{$nav.network.2}}" href="{{$nav.network.0}}" title="{{$nav.network.3}}" >
                                        <span class="desktop-view">{{$nav.network.1}}</span>
                                        <i class="icon s22 icon-th mobile-view"><span class="sr-only">{{$nav.network.1}}</span></i>
-                                       <span id="net-update" class="nav-notify"></span>
+                                       <span id="net-update" class="nav-notification"></span>
                                </a>
                        </li>
                {{/if}}
@@ -56,7 +56,7 @@
                        <li role="menu" aria-haspopup="true" id="nav-messages-linkmenu" class="nav-menu-icon">
                                <a href="{{$nav.messages.0}}" title="{{$nav.messages.1}}">
                                        <span class="icon s22 icon-envelope"><span class="sr-only">{{$nav.messages.1}}</span></span>
-                                       <span id="mail-update" class="nav-notify"></span>
+                                       <span id="mail-update" class="nav-notification"></span>
                                </a>
                        </li>
                {{/if}}
                        <li role="menu" aria-haspopup="true" id="nav-notifications-linkmenu" class="nav-menu-icon">
                                <a title="{{$nav.notifications.1}}">
                                        <span class="icon s22 icon-bell tilted-icon"><span class="sr-only">{{$nav.notifications.1}}</span></span>
-                                       <span id="notify-update" class="nav-notify"></span>
+                                       <span id="notification-update" class="nav-notification"></span>
                                </a>
                                <ul id="nav-notifications-menu" class="menu-popup">
-                                       <li role="menuitem" id="nav-notifications-mark-all"><a onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.1}}</a></li>
+                                       <li role="menuitem" id="nav-notifications-mark-all"><a onclick="notificationMarkAll(); return false;">{{$nav.notifications.mark.1}}</a></li>
                                        <li role="menuitem" id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
                                        <li role="menuitem" class="empty">{{$emptynotifications}}</li>
                                </ul>
 
                {{if $userinfo}}
                        <li role="menu" aria-haspopup="true" id="nav-user-linkmenu" class="nav-menu">
-                               <a accesskey="u" title="{{$sitelocation}}"><img src="{{$userinfo.icon}}" alt="{{$userinfo.name}}"><span id="nav-user-linklabel">{{$userinfo.name}}</span><span id="intro-update" class="nav-notify"></span></a>
+                               <a accesskey="u" title="{{$sitelocation}}"><img src="{{$userinfo.icon}}" alt="{{$userinfo.name}}"><span id="nav-user-linklabel">{{$userinfo.name}}</span><span id="intro-update" class="nav-notification"></span></a>
                                <ul id="nav-user-menu" class="menu-popup">
                                        <li role="menuitem"> <a  class="{{$nav.search.2}}" href="{{$nav.search.0}}" title="{{$nav.search.3}}" >{{$nav.search.1}}</a> </li>
-                                       {{if $nav.introductions}}<li role="menuitem"><a class="{{$nav.introductions.2}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >{{$nav.introductions.1}}</a><span id="intro-update-li" class="nav-notify"></span></li>{{/if}}
+                                       {{if $nav.introductions}}<li role="menuitem"><a class="{{$nav.introductions.2}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >{{$nav.introductions.1}}</a><span id="intro-update-li" class="nav-notification"></span></li>{{/if}}
                                        {{if $nav.contacts}}<li role="menuitem"><a class="{{$nav.contacts.2}}" href="{{$nav.contacts.0}}" title="{{$nav.contacts.3}}" >{{$nav.contacts.1}}</a></li>{{/if}}
-                                       {{if $nav.messages}}<li role="menuitem"><a class="{{$nav.messages.2}}" href="{{$nav.messages.0}}" title="{{$nav.messages.3}}" >{{$nav.messages.1}} <span id="mail-update-li" class="nav-notify"></span></a></li>{{/if}}
+                                       {{if $nav.messages}}<li role="menuitem"><a class="{{$nav.messages.2}}" href="{{$nav.messages.0}}" title="{{$nav.messages.3}}" >{{$nav.messages.1}} <span id="mail-update-li" class="nav-notification"></span></a></li>{{/if}}
                                        {{if $nav.delegation}}<li role="menuitem"><a class="{{$nav.delegation.2}}" href="{{$nav.delegation.0}}" title="{{$nav.delegation.3}}">{{$nav.delegation.1}}</a></li>{{/if}}
                                        {{if $nav.usermenu.1}}<li role="menuitem"><a class="{{$nav.usermenu.1.2}}" href="{{$nav.usermenu.1.0}}" title="{{$nav.usermenu.1.3}}">{{$nav.usermenu.1.1}}</a></li>{{/if}}
                                        {{if $nav.settings}}<li role="menuitem"><a class="{{$nav.settings.2}}" href="{{$nav.settings.0}}" title="{{$nav.settings.3}}">{{$nav.settings.1}}</a></li>{{/if}}
diff --git a/view/theme/vier/templates/profile/advanced.tpl b/view/theme/vier/templates/profile/advanced.tpl
deleted file mode 100644 (file)
index 20c4e84..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-{{if $profile.edit}}
-  <div class="profile-view-actions">
-    <a class="btn" href="{{$profile.edit.0}}" id="profile-view-edit-link" title="{{$profile.edit.3}}">{{$profile.edit.1}}</a>
-  </div>
-{{/if}}
-
-{{include file="section_title.tpl"}}
-
-<dl id="aprofile-fullname" class="aprofile">
- <dt>{{$profile.fullname.0}}</dt>
- <dd>{{$profile.fullname.1}}</dd>
-</dl>
-
-{{if $profile.membersince}}
-<dl id="aprofile-membersince" class="aprofile">
- <dt>{{$profile.membersince.0}}</dt>
- <dd>{{$profile.membersince.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.gender}}
-<dl id="aprofile-gender" class="aprofile">
- <dt>{{$profile.gender.0}}</dt>
- <dd>{{$profile.gender.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.birthday}}
-<dl id="aprofile-birthday" class="aprofile">
- <dt>{{$profile.birthday.0}}</dt>
- <dd>{{$profile.birthday.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.age}}
-<dl id="aprofile-age" class="aprofile">
- <dt>{{$profile.age.0}}</dt>
- <dd>{{$profile.age.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.marital}}
-<dl id="aprofile-marital" class="aprofile">
- <dt><span class="heart">&hearts;</span>  {{$profile.marital.0}}</dt>
- <dd>{{$profile.marital.1}}{{if $profile.marital.with}} ({{$profile.marital.with}}){{/if}}{{if $profile.howlong}} {{$profile.howlong}}{{/if}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.sexual}}
-<dl id="aprofile-sexual" class="aprofile">
- <dt>{{$profile.sexual.0}}</dt>
- <dd>{{$profile.sexual.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.pub_keywords}}
-<dl id="aprofile-tags" class="aprofile">
- <dt>{{$profile.pub_keywords.0}}</dt>
- <dd>{{$profile.pub_keywords.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.homepage}}
-<dl id="aprofile-homepage" class="aprofile">
- <dt>{{$profile.homepage.0}}</dt>
- <dd>{{$profile.homepage.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.hometown}}
-<dl id="aprofile-hometown" class="aprofile">
- <dt>{{$profile.hometown.0}}</dt>
- <dd>{{$profile.hometown.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.politic}}
-<dl id="aprofile-politic" class="aprofile">
- <dt>{{$profile.politic.0}}</dt>
- <dd>{{$profile.politic.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.religion}}
-<dl id="aprofile-religion" class="aprofile">
- <dt>{{$profile.religion.0}}</dt>
- <dd>{{$profile.religion.1}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.about}}
-<dl id="aprofile-about" class="aprofile">
- <dt>{{$profile.about.0}}</dt>
- <dd>{{$profile.about.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.interest}}
-<dl id="aprofile-interest" class="aprofile">
- <dt>{{$profile.interest.0}}</dt>
- <dd>{{$profile.interest.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.likes}}
-<dl id="aprofile-likes" class="aprofile">
- <dt>{{$profile.likes.0}}</dt>
- <dd>{{$profile.likes.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.dislikes}}
-<dl id="aprofile-dislikes" class="aprofile">
- <dt>{{$profile.dislikes.0}}</dt>
- <dd>{{$profile.dislikes.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.contact}}
-<dl id="aprofile-contact" class="aprofile">
- <dt>{{$profile.contact.0}}</dt>
- <dd>{{$profile.contact.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
-{{if $profile.music}}
-<dl id="aprofile-music" class="aprofile">
- <dt>{{$profile.music.0}}</dt>
- <dd>{{$profile.music.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
-{{if $profile.book}}
-<dl id="aprofile-book" class="aprofile">
- <dt>{{$profile.book.0}}</dt>
- <dd>{{$profile.book.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
-{{if $profile.tv}}
-<dl id="aprofile-tv" class="aprofile">
- <dt>{{$profile.tv.0}}</dt>
- <dd>{{$profile.tv.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
-{{if $profile.film}}
-<dl id="aprofile-film" class="aprofile">
- <dt>{{$profile.film.0}}</dt>
- <dd>{{$profile.film.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
-{{if $profile.romance}}
-<dl id="aprofile-romance" class="aprofile">
- <dt>{{$profile.romance.0}}</dt>
- <dd>{{$profile.romance.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-
-{{if $profile.work}}
-<dl id="aprofile-work" class="aprofile">
- <dt>{{$profile.work.0}}</dt>
- <dd>{{$profile.work.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.education}}
-<dl id="aprofile-education" class="aprofile">
- <dt>{{$profile.education.0}}</dt>
- <dd>{{$profile.education.1 nofilter}}</dd>
-</dl>
-{{/if}}
-
-{{if $profile.forumlist}}
-<dl id="aprofile-forumlist" class="aprofile">
- <dt>{{$profile.forumlist.0}}</dt>
- <dd>{{$profile.forumlist.1 nofilter}}</dd>
-</dl>
-{{/if}}
diff --git a/view/theme/vier/templates/profile_edit.tpl b/view/theme/vier/templates/profile_edit.tpl
deleted file mode 100644 (file)
index 066b256..0000000
+++ /dev/null
@@ -1,454 +0,0 @@
-<script>
-        $(document).ready(function() {
-                
-                $('.toggle-section-content').hide();
-                $('.js-section-toggler').click(function(){
-                        $('.toggle-section-content').hide();
-                        $(this).next('.toggle-section-content').toggle();
-                });
-
-        });
-</script>
-
-<h1>{{$banner}}</h1>
-
-<div id="profile-edit-links">
-<ul>
-  <li><a class="btn" href="profile/{{$profile_id}}/view?tab=profile" id="profile-edit-view-link" title="{{$viewprof}}">{{$viewprof}}</a></li>
-  {{if $multi_profiles}}
-    <li><a class="btn" href="{{$profile_clone_link}}" id="profile-edit-clone-link" title="{{$cr_prof}}">{{$cl_prof}}</a></li>
-    <li><a class="btn" href="{{$profile_drop_link}}" id="profile-edit-drop-link" title="{{$del_prof}}" {{$disabled}} >{{$del_prof}}</a></li>
-  {{/if}}
-</ul>
-</div>
-<div id="profile-edit-links-end"></div>
-
-{{$default nofilter}}
-
-<div id="profile-edit-wrapper" >
-
-<form enctype="multipart/form-data" action="profile_photo" method="post">
-  <input type='hidden' name='form_security_token' value='{{$form_security_token_photo}}'>
-  <input type="hidden" name="profile" value="{{$profile_name.2}}" />
-  
-  <!-- Profile picture -->
-{{if $detailled_profile}}
-  <div class="toggle-section js-toggle-section">
-    <a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_picture_section}} &raquo;</a>
-    <div class="js-section toggle-section-content hidden">
-{{/if}}
-      
-      <div id="profile-photo-upload-wrapper">
-        <label id="profile-photo-upload-label" for="profile-photo-upload">{{$lbl_profile_photo}}:</label>
-        <input name="userfile" type="file" id="profile-photo-upload" size="48" />
-      </div>
-
-      <div class="profile-edit-submit-wrapper" >
-        <input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}" />
-      </div>
-      <div class="profile-edit-submit-end"></div>
-    
-{{if $detailled_profile}}
-    </div>
-  </div>
-{{/if}}
-</form>
-
-<form id="profile-edit-form" name="form1" action="profiles/{{$profile_id}}" method="post" >
-  <input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
-
-{{if $detailled_profile}}
-  <!-- Basic information -->
-  <div class="toggle-section js-toggle-section">
-    <a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_basic_section}} &raquo;</a>
-    <div class="js-section toggle-section-content hidden">
-      
-      {{include file="field_yesno.tpl" field=$details}}
-
-      {{if $multi_profiles}}
-        <div id="profile-edit-profile-name-wrapper" >
-          <label id="profile-edit-profile-name-label" for="profile-edit-profile-name" >{{$profile_name.1}} </label>
-          <input type="text" size="32" name="profile_name" id="profile-edit-profile-name" value="{{$profile_name.2}}" /><div class="required">*</div>
-        </div>
-        <div id="profile-edit-profile-name-end"></div>
-      {{else}}
-        <input type="hidden" name="profile_name" id="profile-edit-profile-name" value="{{$profile_name.2}}" />
-      {{/if}}
-      
-      <div id="profile-edit-name-wrapper" >
-        <label id="profile-edit-name-label" for="profile-edit-name" >{{$name.1}} </label>
-        <input type="text" size="32" name="name" id="profile-edit-name" value="{{$name.2}}" />
-      </div>
-      <div id="profile-edit-name-end"></div>
-      
-      <div id="profile-edit-gender-wrapper" >
-        <label id="profile-edit-gender-label" for="gender-select" >{{$lbl_gender}} </label>
-        {{$gender nofilter}}
-      </div>
-      <div id="profile-edit-gender-end"></div>
-      
-      <div id="profile-edit-pdesc-wrapper" >
-        <label id="profile-edit-pdesc-label" for="profile-edit-pdesc" >{{$pdesc.1}} </label>
-        <input type="text" size="32" name="pdesc" id="profile-edit-pdesc" value="{{$pdesc.2}}" />
-      </div>
-      <div id="profile-edit-pdesc-end"></div>
-      
-      <div id="profile-edit-xmpp-wrapper" >
-        <label id="profile-edit-xmpp-label" for="profile-edit-xmpp" >{{$xmpp.1}} </label>
-        <input type="text" size="32" name="xmpp" id="profile-edit-xmpp" value="{{$xmpp.2}}" />
-      </div>
-      <div id="profile-edit-xmpp-desc">{{$xmpp.3}}</div>
-      <div id="profile-edit-xmpp-end"></div>
-
-      <div id="profile-edit-homepage-wrapper" >
-        <label id="profile-edit-homepage-label" for="profile-edit-homepage" >{{$homepage.1}} </label>
-        <input type="text" size="32" name="homepage" id="profile-edit-homepage" value="{{$homepage.2}}" />
-      </div>
-      <div id="profile-edit-homepage-end"></div>
-      
-      <div id="profile-edit-dob-wrapper" >
-        {{$dob nofilter}}
-      </div>
-      <div id="profile-edit-dob-end"></div>
-      
-      {{$hide_friends nofilter}}
-      
-      <div id="about-jot-wrapper">
-        <div id="about-jot-desc">{{$about.1}}</div>
-        <textarea rows="10" cols="72" id="profile-about-text" name="about" style="width:599px;">{{$about.2}}</textarea>
-      </div>
-      <div id="about-jot-end"></div>
-      
-      <div id="contact-jot-wrapper" >
-        <div id="contact-jot-desc">{{$contact.1}}</div>
-        <textarea rows="10" cols="72" id="contact-jot-text" name="contact" style="width:599px;">{{$contact.2}}</textarea>
-      </div>
-      <div id="contact-jot-end"></div>
-      
-      <div id="profile-edit-pubkeywords-wrapper" >
-        <label id="profile-edit-pubkeywords-label" for="profile-edit-pubkeywords" >{{$pub_keywords.1}} </label>
-        <input type="text" size="32" name="pub_keywords" id="profile-edit-pubkeywords" title="{{$lbl_ex2}}" value="{{$pub_keywords.2}}" />
-      </div>
-      <div id="profile-edit-pubkeywords-desc">{{$pub_keywords.3}}</div>
-      <div id="profile-edit-pubkeywords-end"></div>
-      
-      <div id="profile-edit-prvkeywords-wrapper" >
-        <label id="profile-edit-prvkeywords-label" for="profile-edit-prvkeywords" >{{$prv_keywords.1}} </label>
-        <input type="text" size="32" name="prv_keywords" id="profile-edit-prvkeywords" title="{{$lbl_ex2}}" value="{{$prv_keywords.2}}" />
-      </div>
-      <div id="profile-edit-prvkeywords-desc">{{$prv_keywords.3}}</div>
-      <div id="profile-edit-prvkeywords-end"></div>
-      
-      <div class="profile-edit-submit-wrapper" >
-        <input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}" />
-      </div>
-      <div class="profile-edit-submit-end"></div>
-    
-    </div>
-  </div>
-  
-  <!-- About you -->
-  <div class="toggle-section js-toggle-section">
-    <a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_about_section}} &raquo;</a>
-    <div class="js-section toggle-section-content hidden">
-      
-      <div><b>{{$lbl_location_section}}</b></div>
-      
-      <div id="profile-edit-address-wrapper" >
-        <label id="profile-edit-address-label" for="profile-edit-address" >{{$address.1}} </label>
-        <input type="text" size="32" name="address" id="profile-edit-address" value="{{$address.2}}" />
-      </div>
-      <div id="profile-edit-address-end"></div>
-      
-      <div id="profile-edit-locality-wrapper" >
-        <label id="profile-edit-locality-label" for="profile-edit-locality" >{{$locality.1}} </label>
-        <input type="text" size="32" name="locality" id="profile-edit-locality" value="{{$locality.2}}" />
-      </div>
-      <div id="profile-edit-locality-end"></div>
-      
-      <div id="profile-edit-postal-code-wrapper" >
-        <label id="profile-edit-postal-code-label" for="profile-edit-postal-code" >{{$postal_code.1}} </label>
-        <input type="text" size="32" name="postal_code" id="profile-edit-postal-code" value="{{$postal_code.2}}" />
-      </div>
-      <div id="profile-edit-postal-code-end"></div>
-      
-      <div id="profile-edit-country-name-wrapper" >
-        <label id="profile-edit-country-name-label" for="profile-edit-country-name" >{{$country_name.1}} </label>
-        <select name="country_name" id="profile-edit-country-name" onChange="Fill_States('{{$region.2}}');">
-          <option selected="selected" >{{$country_name.2}}</option>
-        </select>
-      </div>
-      <div id="profile-edit-country-name-end"></div>
-      
-      <div id="profile-edit-region-wrapper" >
-        <label id="profile-edit-region-label" for="profile-edit-region" >{{$region.2}} </label>
-        <select name="region" id="profile-edit-region" onChange="Update_Globals();" >
-          <option selected="selected" >{{$region.2}}</option>
-        </select>
-      </div>
-      <div id="profile-edit-region-end"></div>
-      
-      <div id="profile-edit-hometown-wrapper" >
-        <label id="profile-edit-hometown-label" for="profile-edit-hometown" >{{$hometown.1}} </label>
-        <input type="text" size="32" name="hometown" id="profile-edit-hometown" value="{{$hometown.2}}" />
-      </div>
-      <div id="profile-edit-hometown-end"></div>
-      
-      <br>
-      
-      <div><b>{{$lbl_preferences_section}}</b></div>
-      
-      <div id="profile-edit-sexual-wrapper" >
-        <label id="profile-edit-sexual-label" for="sexual-select" >{{$lbl_sexual}} </label>
-        {{$sexual nofilter}}
-      </div>
-      <div id="profile-edit-sexual-end"></div>
-      
-      <div id="profile-edit-politic-wrapper" >
-        <label id="profile-edit-politic-label" for="profile-edit-politic" >{{$politic.1}} </label>
-        <input type="text" size="32" name="politic" id="profile-edit-politic" value="{{$politic.2}}" />
-      </div>
-      <div id="profile-edit-politic-end"></div>
-      
-      <div id="profile-edit-religion-wrapper" >
-        <label id="profile-edit-religion-label" for="profile-edit-religion" >{{$religion.1}} </label>
-        <input type="text" size="32" name="religion" id="profile-edit-religion" value="{{$religion.2}}" />
-      </div>
-      <div id="profile-edit-religion-end"></div>
-      
-      <div id="likes-jot-wrapper">
-        <div id="likes-jot-desc">{{$likes.1}}</div>
-        <textarea rows="10" cols="72" id="likes-jot-text" name="likes" style="width:599px;">{{$likes.2}}</textarea>
-      </div>
-      <div id="likes-jot-end"></div>
-      
-      <div id="dislikes-jot-wrapper">
-        <div id="dislikes-jot-desc">{{$dislikes.1}}</div>
-        <textarea rows="10" cols="72" id="dislikes-jot-text" name="dislikes" style="width:599px;">{{$dislikes.2}}</textarea>
-      </div>
-      <div id="dislikes-jot-end"></div>
-      
-      <div class="profile-edit-submit-wrapper" >
-        <input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}" />
-      </div>
-      <div class="profile-edit-submit-end"></div>
-      
-    </div>
-  </div>
-  
-  <!-- Status -->
-  <div class="toggle-section js-toggle-section">
-    <a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_status_section}} &raquo;</a>
-    <div class="js-section toggle-section-content hidden">
-      
-      <div id="profile-edit-marital-wrapper" >
-        <label id="profile-edit-marital-label" for="profile-edit-marital" >{{$lbl_marital nofilter}} </label>
-        {{$marital nofilter}}
-      </div>
-      <label id="profile-edit-with-label" for="profile-edit-with" > {{$with.1}} </label>
-      <input type="text" size="32" name="with" id="profile-edit-with" title="{{$with.3}}" value="{{$with.2}}" />
-      <label id="profile-edit-howlong-label" for="profile-edit-howlong" > {{$howlong.1}} </label>
-      <input type="text" size="32" name="howlong" id="profile-edit-howlong" title="{{$howlong.1}}" value="{{$howlong.2}}" />
-      <div id="profile-edit-marital-end"></div>
-      
-      <div id="romance-jot-wrapper" >
-        <div id="romance-jot-desc">{{$romance.1}}</div>
-        <textarea rows="10" cols="72" id="romance-jot-text" name="romance" style="width:599px;">{{$romance.2}}</textarea>
-      </div>
-      <div id="romance-jot-end"></div>
-      
-      <div id="work-jot-wrapper">
-        <div id="work-jot-desc">{{$work.1}}</div>
-        <textarea rows="10" cols="72" id="work-jot-text" name="work" style="width:599px;">{{$work.2}}</textarea>
-      </div>
-      <div id="work-jot-end"></div>
-      
-      <div id="education-jot-wrapper" >
-        <div id="education-jot-desc">{{$education.1}}</div>
-        <textarea rows="10" cols="72" id="education-jot-text" name="education" style="width:599px;">{{$education.2}}</textarea>
-      </div>
-      <div id="education-jot-end"></div>
-      
-      <div class="profile-edit-submit-wrapper" >
-        <input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}" />
-      </div>
-      <div class="profile-edit-submit-end"></div>
-      
-    </div>
-  </div>
-  
-  <!-- Interests -->
-  <div class="toggle-section js-toggle-section">
-    <a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_interests_section}} &raquo;</a>
-    <div class="js-section toggle-section-content hidden">
-      
-      <div id="interest-jot-wrapper">
-        <div id="interest-jot-desc">{{$interest.1}}</div>
-        <textarea rows="10" cols="72" id="interest-jot-text" name="interest" style="width:599px;">{{$interest.2}}</textarea>
-      </div>
-      <div id="interest-jot-end"></div>
-      
-      <div id="music-jot-wrapper">
-        <div id="music-jot-desc">{{$music.1}}</div>
-        <textarea rows="10" cols="72" id="music-jot-text" name="music" style="width:599px;">{{$music.2}}</textarea>
-      </div>
-      <div id="music-jot-end"></div>
-
-      <div id="book-jot-wrapper">
-        <div id="book-jot-desc">{{$book.1}}</div>
-        <textarea rows="10" cols="72" id="book-jot-text" name="book" style="width:599px;">{{$book.2}}</textarea>
-      </div>
-      <div id="book-jot-end"></div>
-      
-      <div id="tv-jot-wrapper">
-        <div id="tv-jot-desc">{{$tv.1}}</div>
-        <textarea rows="10" cols="72" id="tv-jot-text" name="tv" style="width:599px;">{{$tv.2}}</textarea>
-      </div>
-      <div id="tv-jot-end"></div>
-      
-      <div id="film-jot-wrapper">
-        <div id="film-jot-desc">{{$film.1}}</div>
-        <textarea rows="10" cols="72" id="film-jot-text" name="film" style="width:599px;">{{$film.2}}</textarea>
-      </div>
-      <div id="film-jot-end"></div>
-      
-      <div class="profile-edit-submit-wrapper" >
-        <input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}" />
-      </div>
-      <div class="profile-edit-submit-end"></div>
-      
-    </div>
-  </div>
-{{else}}
-
-{{if $personal_account}}
-{{include file="field_yesno.tpl" field=$details}}
-{{/if}}
-<div id="profile-edit-profile-name-wrapper" >
-<label id="profile-edit-profile-name-label" for="profile-edit-profile-name" >{{$profile_name.1}} </label>
-<input type="text" size="32" name="profile_name" id="profile-edit-profile-name" value="{{$profile_name.2}}" /><div class="required">*</div>
-</div>
-<div id="profile-edit-profile-name-end"></div>
-
-<div id="profile-edit-name-wrapper" >
-<label id="profile-edit-name-label" for="profile-edit-name" >{{$name.1}} </label>
-<input type="text" size="32" name="name" id="profile-edit-name" value="{{$name.2}}" />
-</div>
-<div id="profile-edit-name-end"></div>
-
-{{if $personal_account}}
-<div id="profile-edit-gender-wrapper" >
-<label id="profile-edit-gender-label" for="gender-select" >{{$lbl_gender}} </label>
-{{$gender nofilter}}
-</div>
-<div id="profile-edit-gender-end"></div>
-
-<div id="profile-edit-dob-wrapper" >
-{{$dob nofilter}}
-</div>
-<div id="profile-edit-dob-end"></div>
-{{/if}}
-
-      <div id="profile-edit-xmpp-wrapper" >
-        <label id="profile-edit-xmpp-label" for="profile-edit-xmpp" >{{$xmpp.1}} </label>
-        <input type="text" size="32" name="xmpp" id="profile-edit-xmpp" value="{{$xmpp.2}}" />
-      </div>
-      <div id="profile-edit-xmpp-desc">{{$xmpp.3}}</div>
-      <div id="profile-edit-xmpp-end"></div>
-
-      <div id="profile-edit-homepage-wrapper" >
-        <label id="profile-edit-homepage-label" for="profile-edit-homepage" >{{$homepage.1}} </label>
-        <input type="text" size="32" name="homepage" id="profile-edit-homepage" value="{{$homepage.2}}" />
-      </div>
-      <div id="profile-edit-homepage-end"></div>
-
-{{$hide_friends nofilter}}
-
-<div id="profile-edit-address-wrapper" >
-<label id="profile-edit-address-label" for="profile-edit-address" >{{$address.1}} </label>
-<input type="text" size="32" name="address" id="profile-edit-address" value="{{$address.2}}" />
-</div>
-<div id="profile-edit-address-end"></div>
-
-<div id="profile-edit-locality-wrapper" >
-<label id="profile-edit-locality-label" for="profile-edit-locality" >{{$locality.1}} </label>
-<input type="text" size="32" name="locality" id="profile-edit-locality" value="{{$locality.2}}" />
-</div>
-<div id="profile-edit-locality-end"></div>
-
-
-<div id="profile-edit-postal-code-wrapper" >
-<label id="profile-edit-postal-code-label" for="profile-edit-postal-code" >{{$postal_code.1}} </label>
-<input type="text" size="32" name="postal_code" id="profile-edit-postal-code" value="{{$postal_code.2}}" />
-</div>
-<div id="profile-edit-postal-code-end"></div>
-
-<div id="profile-edit-country-name-wrapper" >
-<label id="profile-edit-country-name-label" for="profile-edit-country-name" >{{$country_name.1}} </label>
-<select name="country_name" id="profile-edit-country-name" onChange="Fill_States('{{$region.2}}');">
-<option selected="selected" >{{$country_name.2}}</option>
-<option>temp</option>
-</select>
-</div>
-<div id="profile-edit-country-name-end"></div>
-<div id="profile-edit-region-wrapper" >
-<label id="profile-edit-region-label" for="profile-edit-region" >{{$region.1}} </label>
-<select name="region" id="profile-edit-region" onChange="Update_Globals();" >
-<option selected="selected" >{{$region.2}}</option>
-<option>temp</option>
-</select>
-</div>
-<div id="profile-edit-region-end"></div>
-
-<div id="profile-edit-pubkeywords-wrapper" >
-<label id="profile-edit-pubkeywords-label" for="profile-edit-pubkeywords" >{{$pub_keywords.1}} </label>
-<input type="text" size="32" name="pub_keywords" id="profile-edit-pubkeywords" title="{{$lbl_ex2}}" value="{{$pub_keywords.2}}" />
-</div><div id="profile-edit-pubkeywords-desc">{{$pub_keywords.3}}</div>
-<div id="profile-edit-pubkeywords-end"></div>
-
-<div id="profile-edit-prvkeywords-wrapper" >
-<label id="profile-edit-prvkeywords-label" for="profile-edit-prvkeywords" >{{$prv_keywords.1}} </label>
-<input type="text" size="32" name="prv_keywords" id="profile-edit-prvkeywords" title="{{$lbl_ex2}}" value="{{$prv_keywords.2}}" />
-</div><div id="profile-edit-prvkeywords-desc">{{$prv_keywords.3}}</div>
-<div id="profile-edit-prvkeywords-end"></div>
-
-<div id="about-jot-wrapper" >
-<p id="about-jot-desc" >
-{{$about.1}}
-</p>
-
-<textarea rows="10" cols="72" id="profile-about-text" name="about" >{{$about.2}}</textarea>
-
-</div>
-<div id="about-jot-end"></div>
-
-<div class="profile-edit-submit-wrapper" >
-<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}" />
-</div>
-<div class="profile-edit-submit-end"></div>
-
-        <input type="hidden" name="pdesc" id="profile-edit-pdesc" value="{{$pdesc.2}}" />
-        <input type="hidden" id="contact-jot-text" name="contact" value="{{$contact.2}}" />
-        <input type="hidden" name="hometown" id="profile-edit-hometown" value="{{$hometown.2}}" />
-        <input type="hidden" name="politic" id="profile-edit-politic" value="{{$politic.2}}" />
-        <input type="hidden" name="religion" id="profile-edit-religion" value="{{$religion.2}}" />
-        <input type="hidden" id="likes-jot-text" name="likes" value="{{$likes.2}}" />
-        <input type="hidden" id="dislikes-jot-text" name="dislikes" value="{{$dislikes.2}}" />
-        <input type="hidden" name="marital" id="profile-edit-marital" value="{{$marital.2}}" />
-        <input type="hidden" name="with" id="profile-edit-with" value="{{$with.2}}" />
-        <input type="hidden" name="howlong" id="profile-edit-howlong" value="{{$howlong.2}}" />
-        <input type="hidden" name="sexual" id="profile-edit-sexual" value="{{$sexual.2}}" />
-        <input type="hidden" id="romance-jot-text" name="romance" value="{{$romance.2}}" />
-        <input type="hidden" id="work-jot-text" name="work" value="{{$work.2}}" />
-        <input type="hidden" id="education-jot-text" name="education" value="{{$education.2}}" />
-        <input type="hidden" id="interest-jot-text" name="interest" value="{{$interest.2}}" />
-        <input type="hidden" id="music-jot-text" name="music" value="{{$music.2}}" />
-        <input type="hidden" id="book-jot-text" name="book" value="{{$book.2}}" />
-        <input type="hidden" id="tv-jot-text" name="tv" value="{{$tv.2}}" />
-        <input type="hidden" id="film-jot-text" name="film" value="{{$film.2}}" />
-
-{{/if}}
-  
-</form>
-</div>
-<script type="text/javascript">Fill_Country('{{$country_name.2}}');Fill_States('{{$region.2}}');</script>
diff --git a/view/theme/vier/templates/profile_edlink.tpl b/view/theme/vier/templates/profile_edlink.tpl
deleted file mode 100644 (file)
index ebf9046..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-<div class="clear"></div>
diff --git a/view/theme/vier/templates/settings/profile/index.tpl b/view/theme/vier/templates/settings/profile/index.tpl
new file mode 100644 (file)
index 0000000..eab7c2c
--- /dev/null
@@ -0,0 +1,171 @@
+<script>
+       $(document).ready(function () {
+               //$('.toggle-section-content + .toggle-section-content').hide();
+               $('.js-section-toggler').click(function () {
+                       $('.toggle-section-content').hide();
+                       $(this).next('.toggle-section-content').toggle();
+               });
+       });
+</script>
+
+<h1>{{$banner}}</h1>
+
+<div id="profile-edit-links">
+       <ul>
+               <li><a class="btn" href="profile/{{$nickname}}" id="profile-edit-view-link" title="{{$viewprof}}">{{$viewprof}}</a></li>
+       </ul>
+</div>
+<div id="profile-edit-links-end"></div>
+
+<div id="profile-edit-wrapper">
+       <form enctype="multipart/form-data" action="settings/profile/photo" method="post">
+               <input type="hidden" name="form_security_token" value="{{$form_security_token_photo}}">
+
+               <!-- Profile picture -->
+               <div class="toggle-section js-toggle-section">
+                       <a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_picture_section}} &raquo;</a>
+                       <div class="js-section toggle-section-content hidden">
+
+                               <div id="profile-photo-upload-wrapper">
+                                       <label id="profile-photo-upload-label" for="profile-photo-upload">{{$lbl_profile_photo}}:</label>
+                                       <input name="userfile" type="file" id="profile-photo-upload" size="48"/>
+                               </div>
+
+                               <div class="profile-edit-submit-wrapper">
+                                       <input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
+                               </div>
+                               <div class="profile-edit-submit-end"></div>
+
+                       </div>
+               </div>
+       </form>
+
+       <form id="profile-edit-form" name="form1" action="" method="post">
+               <input type="hidden" name="form_security_token" value="{{$form_security_token}}">
+
+               <!-- Basic information -->
+               <div class="toggle-section js-toggle-section">
+                       <a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_personal_section}} &raquo;</a>
+                       <div class="js-section toggle-section-content hidden">
+
+                               <div id="profile-edit-name-wrapper">
+                                       <label id="profile-edit-name-label" for="profile-edit-name">{{$name.1}} </label>
+                                       <input type="text" size="32" name="name" id="profile-edit-name" value="{{$name.2}}"/>
+                               </div>
+                               <div id="profile-edit-name-end"></div>
+
+                               <div id="profile-edit-pdesc-wrapper">
+                                       <label id="profile-edit-pdesc-label" for="profile-edit-pdesc">{{$pdesc.1}} </label>
+                                       <input type="text" size="32" name="pdesc" id="profile-edit-pdesc" value="{{$pdesc.2}}"/>
+                               </div>
+                               <div id="profile-edit-pdesc-end"></div>
+
+                               <div id="profile-edit-xmpp-wrapper">
+                                       <label id="profile-edit-xmpp-label" for="profile-edit-xmpp">{{$xmpp.1}} </label>
+                                       <input type="text" size="32" name="xmpp" id="profile-edit-xmpp" value="{{$xmpp.2}}"/>
+                               </div>
+                               <div id="profile-edit-xmpp-desc">{{$xmpp.3}}</div>
+                               <div id="profile-edit-xmpp-end"></div>
+
+                               <div id="profile-edit-homepage-wrapper">
+                                       <label id="profile-edit-homepage-label" for="profile-edit-homepage">{{$homepage.1}} </label>
+                                       <input type="text" size="32" name="homepage" id="profile-edit-homepage" value="{{$homepage.2}}"/>
+                               </div>
+                               <div id="profile-edit-homepage-end"></div>
+
+                               <div id="profile-edit-dob-wrapper">
+                                       {{$dob nofilter}}
+                               </div>
+                               <div id="profile-edit-dob-end"></div>
+
+                               {{$hide_friends nofilter}}
+
+                               <div id="profile-edit-pubkeywords-wrapper">
+                                       <label id="profile-edit-pubkeywords-label" for="profile-edit-pubkeywords">{{$pub_keywords.1}} </label>
+                                       <input type="text" size="32" name="pub_keywords" id="profile-edit-pubkeywords" title="{{$lbl_ex2}}" value="{{$pub_keywords.2}}"/>
+                               </div>
+                               <div id="profile-edit-pubkeywords-desc">{{$pub_keywords.3}}</div>
+                               <div id="profile-edit-pubkeywords-end"></div>
+
+                               <div id="profile-edit-prvkeywords-wrapper">
+                                       <label id="profile-edit-prvkeywords-label" for="profile-edit-prvkeywords">{{$prv_keywords.1}} </label>
+                                       <input type="text" size="32" name="prv_keywords" id="profile-edit-prvkeywords" title="{{$lbl_ex2}}" value="{{$prv_keywords.2}}"/>
+                               </div>
+                               <div id="profile-edit-prvkeywords-desc">{{$prv_keywords.3}}</div>
+                               <div id="profile-edit-prvkeywords-end"></div>
+
+                               <div class="profile-edit-submit-wrapper">
+                                       <input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
+                               </div>
+                               <div class="profile-edit-submit-end"></div>
+
+                       </div>
+               </div>
+               <!-- About you -->
+               <div class="toggle-section js-toggle-section">
+                       <a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_location_section}} &raquo;</a>
+                       <div class="js-section toggle-section-content hidden">
+
+                               <div id="profile-edit-address-wrapper">
+                                       <label id="profile-edit-address-label" for="profile-edit-address">{{$address.1}} </label>
+                                       <input type="text" size="32" name="address" id="profile-edit-address" value="{{$address.2}}"/>
+                               </div>
+                               <div id="profile-edit-address-end"></div>
+
+                               <div id="profile-edit-locality-wrapper">
+                                       <label id="profile-edit-locality-label" for="profile-edit-locality">{{$locality.1}} </label>
+                                       <input type="text" size="32" name="locality" id="profile-edit-locality" value="{{$locality.2}}"/>
+                               </div>
+                               <div id="profile-edit-locality-end"></div>
+
+                               <div id="profile-edit-postal-code-wrapper">
+                                       <label id="profile-edit-postal-code-label" for="profile-edit-postal-code">{{$postal_code.1}} </label>
+                                       <input type="text" size="32" name="postal_code" id="profile-edit-postal-code" value="{{$postal_code.2}}"/>
+                               </div>
+                               <div id="profile-edit-postal-code-end"></div>
+
+                               <div id="profile-edit-country-name-wrapper">
+                                       <label id="profile-edit-country-name-label" for="profile-edit-country-name">{{$country_name.1}} </label>
+                                       <select name="country_name" id="profile-edit-country-name" onChange="Fill_States('{{$region.2}}');">
+                                               <option selected="selected">{{$country_name.2}}</option>
+                                       </select>
+                               </div>
+                               <div id="profile-edit-country-name-end"></div>
+
+                               <div id="profile-edit-region-wrapper">
+                                       <label id="profile-edit-region-label" for="profile-edit-region">{{$region.1}} </label>
+                                       <select name="region" id="profile-edit-region" onChange="Update_Globals();">
+                                               <option selected="selected">{{$region.2}}</option>
+                                       </select>
+                               </div>
+                               <div id="profile-edit-region-end"></div>
+
+                               <div class="profile-edit-submit-wrapper">
+                                       <input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
+                               </div>
+                               <div class="profile-edit-submit-end"></div>
+                       </div>
+               </div>
+               <!-- Interests -->
+               <div class="toggle-section js-toggle-section">
+                       <a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_custom_fields_section}} &raquo;</a>
+                       <div class="js-section toggle-section-content hidden">
+                               {{$custom_fields_description nofilter}}
+                               <div id="profile-custom-fields">
+                               {{foreach $custom_fields as $custom_field}}
+                                       {{include file="settings/profile/field/edit.tpl" profile_field=$custom_field}}
+                               {{/foreach}}
+                               </div>
+
+                               <div class="profile-edit-submit-wrapper">
+                                       <input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
+                               </div>
+                               <div class="profile-edit-submit-end"></div>
+                       </div>
+               </div>
+       </form>
+</div>
+<script type="text/javascript">
+       Fill_Country('{{$country_name.2}}');
+       Fill_States('{{$region.2}}');
+</script>
diff --git a/view/theme/vier/templates/settings/profile/link.tpl b/view/theme/vier/templates/settings/profile/link.tpl
new file mode 100644 (file)
index 0000000..ebf9046
--- /dev/null
@@ -0,0 +1,2 @@
+
+<div class="clear"></div>
index 9188bcbc99dbfb41b9b21a27a0f314fb96c48e80..e5d5e1ce971a48a2239298f876c9bb183b3b8e04 100644 (file)
@@ -140,14 +140,14 @@ function vier_community_info()
 
        // last 9 users
        if ($show_lastusers) {
-               $publish = (DI::config()->get('system', 'publish_all') ? '' : " AND `publish` = 1 ");
+               $publish = (DI::config()->get('system', 'publish_all') ? '' : "`publish` = 1");
                $order = " ORDER BY `register_date` DESC ";
 
                $tpl = Renderer::getMarkupTemplate('ch_directory_item.tpl');
 
                $r = q("SELECT `profile`.*, `user`.`nickname`
                                FROM `profile` LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
-                               WHERE `is-default` = 1 $publish AND `user`.`blocked` = 0 $order LIMIT %d , %d ",
+                               WHERE $publish AND `user`.`blocked` = 0 $order LIMIT %d , %d ",
                        0,
                        9
                );