Merge remote-tracking branch 'upstream/develop' into parent-view

This commit is contained in:
Michael 2023-05-29 06:53:02 +00:00
commit 1129e8f17d
147 changed files with 1736 additions and 1725 deletions

View file

@ -17,29 +17,29 @@ Have a look at the [installation documentation](doc/Install.md) for further info
### Friendica Screenshots
| ![Frio theme in mobile browser](images/screenshots/friendica-frio-mobile-profile-1.png?raw=true "Frio theme in mobile browser") ![Frio theme in mobile browser](images/screenshots/friendica-frio-mobile-profile-2.png?raw=true "Frio theme in mobile browser")
|:--:|
|*Frio theme, mobile browser. Timeline and composer view.*|
|![Frio theme in desktop browser](images/screenshots/friendica-frio-green-profile-1.png?raw=true "Frio theme in desktop browser")
|*Frio theme, desktop browser. Timeline view, contact info popped up, control menu open.*|
|![Frio theme in desktop browser](images/screenshots/friendica-frio-green-profile-2.png?raw=true "Frio theme in desktop browser")
|*Frio theme, desktop browser. Menu open for controlling individual posts.*|
|![Frio theme in desktop browser](images/screenshots/friendica-frio-red-profile-3.png?raw=true "Frio theme in desktop browser")
|*Frio theme, desktop browser. Profile view, notification menu open.*|
|![Frio theme in desktop browser](images/screenshots/friendica-frio-red-profile-2.png?raw=true "Frio theme in desktop browser")
|*Number of new posts, in total and by group.*|
|![Frio theme in desktop browser](images/screenshots/friendica-frio-red-profile-1.png?raw=true "Frio theme in desktop browser")
|*Calender with popup of event.*|
|![Frio theme default colour in standard browser on tablet](images/screenshots/friendica-frio-default-profile-1.png?raw=true "Frio theme default colour in standard browser on tablet")
|*Notifications menu and private messages counter, standard browser on tablet.*|
|![Frio theme in desktop browser](images/screenshots/friendica-frio-brown-profile-2.png?raw=true "Frio theme in desktop browser")
|*Number of visible contacts, standard browser.*|
|![Frio theme in desktop browser](images/screenshots/friendica-frio-brown-profile-1.png?raw=true "Frio theme in desktop browser")
|*Network posts chronologically ordered, standard browser.*|
|![Vier theme in desktop browser](images/screenshots/friendica-vier-profile.png?raw=true "Vier theme in desktop browser")
|*Vier theme, desktop browser. Public timeline view.*|
|![Vier theme in desktop browser](images/screenshots/friendica-vier-community.png?raw=true "Vier theme in desktop browser")
|*Vier theme, desktop browser. Community post displayed.*|
| ![Frio theme in mobile browser](images/screenshots/friendica-frio-mobile-profile-1.png?raw=true "Frio theme in mobile browser") ![Frio theme in mobile browser](images/screenshots/friendica-frio-mobile-profile-2.png?raw=true "Frio theme in mobile browser") |
|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
| *Frio theme, mobile browser. Timeline and composer view.* |
| ![Frio theme in desktop browser](images/screenshots/friendica-frio-green-profile-1.png?raw=true "Frio theme in desktop browser") |
| *Frio theme, desktop browser. Timeline view, contact info popped up, control menu open.* |
| ![Frio theme in desktop browser](images/screenshots/friendica-frio-green-profile-2.png?raw=true "Frio theme in desktop browser") |
| *Frio theme, desktop browser. Menu open for controlling individual posts.* |
| ![Frio theme in desktop browser](images/screenshots/friendica-frio-red-profile-3.png?raw=true "Frio theme in desktop browser") |
| *Frio theme, desktop browser. Profile view, notification menu open.* |
| ![Frio theme in desktop browser](images/screenshots/friendica-frio-red-profile-2.png?raw=true "Frio theme in desktop browser") |
| *Number of new posts, in total and by circle.* |
| ![Frio theme in desktop browser](images/screenshots/friendica-frio-red-profile-1.png?raw=true "Frio theme in desktop browser") |
| *Calendar with popup of event.* |
| ![Frio theme default colour in standard browser on tablet](images/screenshots/friendica-frio-default-profile-1.png?raw=true "Frio theme default colour in standard browser on tablet") |
| *Notifications menu and private messages counter, standard browser on tablet.* |
| ![Frio theme in desktop browser](images/screenshots/friendica-frio-brown-profile-2.png?raw=true "Frio theme in desktop browser") |
| *Number of visible contacts, standard browser.* |
| ![Frio theme in desktop browser](images/screenshots/friendica-frio-brown-profile-1.png?raw=true "Frio theme in desktop browser") |
| *Network posts chronologically ordered, standard browser.* |
| ![Vier theme in desktop browser](images/screenshots/friendica-vier-profile.png?raw=true "Vier theme in desktop browser") |
| *Vier theme, desktop browser. Public timeline view.* |
| ![Vier theme in desktop browser](images/screenshots/friendica-vier-community.png?raw=true "Vier theme in desktop browser") |
| *Vier theme, desktop browser. Community post displayed.* |
## Endorsements

View file

@ -252,9 +252,9 @@ CREATE TABLE IF NOT EXISTS `permissionset` (
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner id of this permission set',
`allow_cid` mediumtext COMMENT 'Access Control - list of allowed contact.id \'<19><78>\'',
`allow_gid` mediumtext COMMENT 'Access Control - list of allowed groups',
`allow_gid` mediumtext COMMENT 'Access Control - list of allowed circles',
`deny_cid` mediumtext COMMENT 'Access Control - list of denied contact.id',
`deny_gid` mediumtext COMMENT 'Access Control - list of denied groups',
`deny_gid` mediumtext COMMENT 'Access Control - list of denied circles',
PRIMARY KEY(`id`),
INDEX `uid_allow_cid_allow_gid_deny_cid_deny_gid` (`uid`,`allow_cid`(50),`allow_gid`(30),`deny_cid`(50),`deny_gid`(30)),
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
@ -457,9 +457,9 @@ CREATE TABLE IF NOT EXISTS `attach` (
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'creation time',
`edited` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'last edit time',
`allow_cid` mediumtext COMMENT 'Access Control - list of allowed contact.id \'<19><78>',
`allow_gid` mediumtext COMMENT 'Access Control - list of allowed groups',
`allow_gid` mediumtext COMMENT 'Access Control - list of allowed circles',
`deny_cid` mediumtext COMMENT 'Access Control - list of denied contact.id',
`deny_gid` mediumtext COMMENT 'Access Control - list of denied groups',
`deny_gid` mediumtext COMMENT 'Access Control - list of denied circles',
`backend-class` tinytext COMMENT 'Storage backend class',
`backend-ref` text COMMENT 'Storage backend data reference',
PRIMARY KEY(`id`),
@ -662,9 +662,9 @@ CREATE TABLE IF NOT EXISTS `event` (
`nofinish` boolean NOT NULL DEFAULT '0' COMMENT 'if event does have no end this is 1',
`ignore` boolean NOT NULL DEFAULT '0' COMMENT '0 or 1',
`allow_cid` mediumtext COMMENT 'Access Control - list of allowed contact.id \'<19><78>\'',
`allow_gid` mediumtext COMMENT 'Access Control - list of allowed groups',
`allow_gid` mediumtext COMMENT 'Access Control - list of allowed circles',
`deny_cid` mediumtext COMMENT 'Access Control - list of denied contact.id',
`deny_gid` mediumtext COMMENT 'Access Control - list of denied groups',
`deny_gid` mediumtext COMMENT 'Access Control - list of denied circles',
PRIMARY KEY(`id`),
INDEX `uid_start` (`uid`,`start`),
INDEX `cid` (`cid`),
@ -716,29 +716,29 @@ CREATE TABLE IF NOT EXISTS `group` (
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'Owner User id',
`visible` boolean NOT NULL DEFAULT '0' COMMENT '1 indicates the member list is not private',
`deleted` boolean NOT NULL DEFAULT '0' COMMENT '1 indicates the group has been deleted',
`deleted` boolean NOT NULL DEFAULT '0' COMMENT '1 indicates the circle has been deleted',
`cid` int unsigned COMMENT 'Contact id of forum. When this field is filled then the members are synced automatically.',
`name` varchar(255) NOT NULL DEFAULT '' COMMENT 'human readable name of group',
`name` varchar(255) NOT NULL DEFAULT '' COMMENT 'human readable name of circle',
PRIMARY KEY(`id`),
INDEX `uid` (`uid`),
INDEX `cid` (`cid`),
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE,
FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='privacy groups, group info';
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='privacy circles, circle info';
--
-- TABLE group_member
--
CREATE TABLE IF NOT EXISTS `group_member` (
`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
`gid` int unsigned NOT NULL DEFAULT 0 COMMENT 'groups.id of the associated group',
`contact-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'contact.id of the member assigned to the associated group',
`gid` int unsigned NOT NULL DEFAULT 0 COMMENT 'group.id of the associated circle',
`contact-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'contact.id of the member assigned to the associated circle',
PRIMARY KEY(`id`),
INDEX `contactid` (`contact-id`),
UNIQUE INDEX `gid_contactid` (`gid`,`contact-id`),
FOREIGN KEY (`gid`) REFERENCES `group` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
FOREIGN KEY (`contact-id`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='privacy groups, member info';
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='privacy circles, member info';
--
-- TABLE gserver-tag
@ -1114,9 +1114,9 @@ CREATE TABLE IF NOT EXISTS `photo` (
`scale` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
`profile` boolean NOT NULL DEFAULT '0' COMMENT '',
`allow_cid` mediumtext COMMENT 'Access Control - list of allowed contact.id \'<19><78>\'',
`allow_gid` mediumtext COMMENT 'Access Control - list of allowed groups',
`allow_gid` mediumtext COMMENT 'Access Control - list of allowed circles',
`deny_cid` mediumtext COMMENT 'Access Control - list of denied contact.id',
`deny_gid` mediumtext COMMENT 'Access Control - list of denied groups',
`deny_gid` mediumtext COMMENT 'Access Control - list of denied circles',
`accessible` boolean NOT NULL DEFAULT '0' COMMENT 'Make photo publicly accessible, ignoring permissions',
`backend-class` tinytext COMMENT 'Storage backend class',
`backend-ref` text COMMENT 'Storage backend data reference',

View file

@ -454,7 +454,7 @@ Ex: Wed May 23 06:01:13 +0000 2007
<tr>
<td><code>allow_gid</code></td>
<td>String (angle-brackets escaped integers)</td>
<td>Optional. List of allowed group ids</td>
<td>Optional. List of allowed circle ids</td>
</tr>
<tr>
@ -466,7 +466,7 @@ Ex: Wed May 23 06:01:13 +0000 2007
<tr>
<td><code>deny_gid</code></td>
<td>String (angle-brackets escaped integers)</td>
<td>Optional. List of disallowed group ids</td>
<td>Optional. List of disallowed circle ids</td>
</tr>
</tbody>
@ -984,7 +984,7 @@ Identical to [the Twitter Media Object](https://developer.twitter.com/en/docs/tw
<tr>
<td><code>allow_gid</code></td>
<td>String (ACL)</td>
<td>List of contact group ids wrapped in angle brackets allowed to access the photo.</td>
<td>List of contact circle ids wrapped in angle brackets allowed to access the photo.</td>
</tr>
<tr>
@ -996,7 +996,7 @@ Identical to [the Twitter Media Object](https://developer.twitter.com/en/docs/tw
<tr>
<td><code>deny_gid</code></td>
<td>String (ACL)</td>
<td>List of contact group ids wrapped in angle brackets forbidden to access the photo.</td>
<td>List of contact circle ids wrapped in angle brackets forbidden to access the photo.</td>
</tr>
<tr>

View file

@ -39,8 +39,8 @@ Create a new event for the current logged in user.
- `publish` : (optional) create message for event
- `allow_cid` : (optional) ACL-formatted list of allowed contact ids if private event
- `allow_gid` : (optional) ACL-formatted list of disallowed contact ids if private event
- `deny_cid` : (optional) ACL-formatted list of allowed group ids if private event
- `deny_gid` : (optional) ACL-formatted list of disallowed group ids if private event
- `deny_cid` : (optional) ACL-formatted list of allowed circle ids if private event
- `deny_gid` : (optional) ACL-formatted list of disallowed circle ids if private event
### POST api/friendica/event_delete
@ -323,33 +323,37 @@ On error:
---
### GET api/friendica/group_show
### GET api/friendica/circle_show
Return all or a specified group of the user with the containing contacts as array.
Alternatively: GET api/friendica/group_show (Backward compatibility)
Return all or a specified circle of the user with the containing contacts as array.
#### Parameters
* `gid`: optional, if not given, API returns all groups of the user
* `gid`: optional, if not given, API returns all circles of the user
#### Return values
Array of:
* `name`: name of the group
* `gid`: id of the group
* `name`: name of the circle
* `gid`: id of the circle
* `user`: array of [Contacts](help/API-Entities#Contact)
### POST api/friendica/group_create
### POST api/friendica/circle_create
Create the group with the posted array of contacts as members.
Alternatively: POST api/friendica/group_create
Create the circle with the posted array of contacts as members.
#### Parameters
* `name`: name of the group to be created
* `name`: name of the circle to be created
#### POST data
JSON data as Array like the result of [GET api/friendica/group_show](#GET+api%2Ffriendica%2Fgroup_show):
JSON data as Array like the result of [GET api/friendica/circle_show](#GET+api%2Ffriendica%2Fcircle_show):
* `gid`
* `name`
@ -360,23 +364,25 @@ JSON data as Array like the result of [GET api/friendica/group_show](#GET+api%2F
Array of:
* `success`: true if successfully created or reactivated
* `gid`: gid of the created group
* `name`: name of the created group
* `gid`: gid of the created circle
* `name`: name of the created circle
* `status`: "missing user" | "reactivated" | "ok"
* `wrong users`: array of users, which were not available in the contact table
### POST api/friendica/group_update
### POST api/friendica/circle_update
Update the group with the posted array of contacts as members (post all members of the group to the call; function will remove members not posted).
Alternatively: POST api/friendica/group_update
Update the circle with the posted array of contacts as members (post all members of the circle to the call; function will remove members not posted).
#### Parameters
* `gid`: id of the group to be changed
* `name`: name of the group to be changed
* `gid`: id of the circle to be changed
* `name`: name of the circle to be changed
#### POST data
JSON data as array like the result of [GET api/friendica/group_show](#GET+api%2Ffriendica%2Fgroup_show):
JSON data as array like the result of [GET api/friendica/circle_show](#GET+api%2Ffriendica%2Fcircle_show):
* `gid`
* `name`
@ -387,27 +393,29 @@ JSON data as array like the result of [GET api/friendica/group_show](#GET+api%2F
Array of:
* `success`: true if successfully updated
* `gid`: gid of the changed group
* `name`: name of the changed group
* `gid`: gid of the changed circle
* `name`: name of the changed circle
* `status`: "missing user" | "ok"
* `wrong users`: array of users, which were not available in the contact table
### POST api/friendica/group_delete
### POST api/friendica/circle_delete
Delete the specified group of contacts; API call need to include the correct gid AND name of the group to be deleted.
Alternatively: POST api/friendica/group_delete
Delete the specified circle of contacts; API call need to include the correct gid AND name of the circle to be deleted.
#### Parameters
* `gid`: id of the group to be deleted
* `name`: name of the group to be deleted
* `gid`: id of the circle to be deleted
* `name`: name of the circle to be deleted
#### Return values
Array of:
* `success`: true if successfully deleted
* `gid`: gid of the deleted group
* `name`: name of the deleted group
* `gid`: gid of the deleted circle
* `name`: name of the deleted circle
* `status`: "deleted" if successfully deleted
* `wrong users`: empty array
@ -556,7 +564,7 @@ Alias of [`api/friendica/photo/update`](#POST+api%2Ffriendica%2Fphoto%2Fupdate)
Saves data for the scales 0-2 to database (see above for scale description).
Call adds non-public entries to items table to enable authenticated contacts to comment/like the photo.
Client should pay attention to the fact that updated access rights are not transferred to the contacts. i.e. public photos remain publicly visible if they have been commented/liked before setting visibility back to a limited group.
Client should pay attention to the fact that updated access rights are not transferred to the contacts. i.e. public photos remain publicly visible if they have been commented/liked before setting visibility back to a limited circle.
Currently it is best to inform user that updating rights is not the right way to do this, and offer a solution to add photo as a new photo with the new rights instead.
#### Parameters

View file

@ -211,7 +211,7 @@ Example:
- `title`: Explicitly sets the title for a post status, ignored if used on a comment status. For post statuses the legacy behavior is to use any "spoiler text" as the title if it is provided. If both the title and spoiler text are provided for a post status then they will each be used for their respective roles. If no title is provided then the legacy behavior will persist. If you want to create a post with no title but spoiler text then explicitly set the title but set it to an empty string `""`.
- [`POST /api/v1/statuses`](https://docs.joinmastodon.org/methods/statuses/#create)
- Does not support `polls` argument as Friendica does not have polls
- Additionally to the static values `public`, `unlisted` and `private`, the `visibility` parameter can contain a numeric value with a group id.
- Additionally to the static values `public`, `unlisted` and `private`, the `visibility` parameter can contain a numeric value with a circle id.
- Additional field `quote_id` for the post that is being quote reshared
- Additional fields `friendica` for Friendica specific parameters:
- `title`: Explicitly sets the title for a post status, ignored if used on a comment status. For post statuses the legacy behavior is to use any "spoiler text" as the title if it is provided. If both the title and spoiler text are provided for a post status then they will each be used for their respective roles. If no title is provided then the legacy behavior will persist. If you want to create a post with no title but spoiler text then explicitly set the title but set it to an empty string `""`.

View file

@ -48,7 +48,7 @@ General
* i - Only show ignored contacts
* y - Only show archived contacts
* h - Only show hidden contacts
* e - Edit contact groups
* e - Edit contact circles
../contact (single contact view)
-------------------------------

View file

@ -101,7 +101,7 @@ See Also
* [Global Directory](help/Making-Friends#The+Directories)
* [Groups and Privacy](help/Groups-and-Privacy)
* [Circles and Privacy](help/Circles-and-Privacy)
* [Move Account](help/Move-Account)

View file

@ -1,55 +1,55 @@
Groups and Privacy
Circles and Privacy
==================
* [Home](help)
Groups are merely collections of friends.
Circles are merely collections of friends.
But Friendica uses these to unlock some very powerful features.
**Setting Up Groups**
**Setting Up Circles**
To create a group, visit your Friendica "Contacts" page and select "Create a new group".
Give the group a name.
To create a circle, visit your Friendica "Contacts" page and select "Create a new circle".
Give the circle a name.
This brings you to a page where you can select the group members.
This brings you to a page where you can select the circle members.
You will have two boxes on this page.
The top box is the roster of current group members.
Below that is another box containing all of your friends who are *not* members of the group.
The top box is the roster of current circle members.
Below that is another box containing all of your friends who are *not* members of the circle.
If you click on a photo of a person who isn't in the group, they will be put into the group.
If you click on a photo of a person who is in the group, they will be removed from it.
If you click on a photo of a person who isn't in the circle, they will be put into the circle.
If you click on a photo of a person who is in the circle, they will be removed from it.
**Access Control**
Once you have created a group, you may use it in any access control list.
Once you have created a circle, you may use it in any access control list.
This is the little lock icon beneath the status update box on your home page.
If you click this you can select who can see and who can *not* see the post you are about to make..
These can be individual people or groups.
These can be individual people or circles.
On your "Network" page you will find posts and conversation from everybody in your network.
You may select an individual group on this page to show conversations pertaining only to members of that group.
You may select an individual circle on this page to show conversations pertaining only to members of that circle.
But wait, there's more...
If you look carefully when visiting a group from your Network page, the lock icon under the status update box has an exclamation mark next to it.
If you look carefully when visiting a circle from your Network page, the lock icon under the status update box has an exclamation mark next to it.
This is meant to draw attention to that lock.
Click the lock.
You will see that since you are only viewing a certain group of people, your status updates while on that screen default to only being seen by that same group of people.
You will see that since you are only viewing a certain circle of people, your status updates while on that screen default to only being seen by that same circle of people.
This is how you keep your future employers from seeing what you write to your drinking buddies.
You can over-ride this setting, but this makes it easy to separate your conversations into different friend circles.
**Default Post Privacy**
By default, Friendica assumes that you want all of your posts to be private.
Therefore, when you sign up, Friendica creates a group for you that it will automatically add all of your contacts to.
All of your posts are restricted to that group by default.
Therefore, when you sign up, Friendica creates a circle for you that it will automatically add all of your contacts to.
All of your posts are restricted to that circle by default.
Note that this behaviour can be overridden by your site admin, in which case your posts will be "public" (i.e. visible to the entire Internet) by default.
If you want your posts to be "public" by default, you can change your default post permissions on your Settings page.
You also have the option there to change which groups you post to by default, or to change which group your new contacts get placed into by default.
You also have the option there to change which circles you post to by default, or to change which circle your new contacts get placed into by default.
**Privacy Concerns To Be Aware Of**

View file

@ -14,7 +14,7 @@ Friendica Documentation and Resources
* You and other users
* [Connectors](help/Connectors)
* [Making Friends](help/Making-Friends)
* [Groups and Privacy](help/Groups-and-Privacy)
* [Circles and Privacy](help/Circles-and-Privacy)
* [Tags and Mentions](help/Tags-and-Mentions)
* [Community Forums](help/Forums)
* [Chats](help/Chats)

View file

@ -20,7 +20,7 @@ You'll also see a link to a **Global Directory**.
There are several global directories across the globe that regularly exchange information with each other.
The specific global directory that you see usually depends on where your server is located.
If you click through to the global directory, you will be presented with a list of everybody who choses to be listed across all instances of Friendica.
You will also see a "Show Community Forums" link, which will direct you to Groups, Forums and Fanpages.
You will also see a "Show Community Forums" link, which will direct you to Circles, Forums and Fanpages.
You connect to people, groups and forums in the same way, except groups and forums will automatically accept your introduction request, whereas a human will approve you manually.
Connect to other Friendica users

View file

@ -8,7 +8,7 @@ How to move your account between servers
* Go to "Settings" -> "[Export personal data](uexport)"
* Click on "Export account" to save your account data.
* **Save the file in a secure place!** It contains your details, your contacts, groups, and personal settings. It also contains your secret keys to authenticate yourself to your contacts.
* **Save the file in a secure place!** It contains your details, your contacts, circles, and personal settings. It also contains your secret keys to authenticate yourself to your contacts.
* Go to your new server, and open *http://newserver.com/user/import* (there is not a direct link to this page at the moment). Please consider that this is only possible on servers with open registration. On other systems only the administrator can add accounts with an uploaded file.
* Do NOT create a new account prior to importing your old settings - user import should be used *instead* of register.
* Load your saved account file and click "Import".
@ -17,7 +17,7 @@ How to move your account between servers
Friendica contacts
---
Friendica will recreate your account on the new server, with your contacts and groups.
Friendica will recreate your account on the new server, with your contacts and circles.
A message is sent to Friendica contacts, to inform them about your move:
If your contacts are running on an updated server, your details on their side will be automatically updated.

View file

@ -4,7 +4,6 @@ Here are some more things to help get you started:
**Groups**
- <a href="http://forum.friendi.ca/profile/helpers">Friendica Support</a> - problems? This is the place to ask.
**Documentation**

View file

@ -37,9 +37,9 @@ If you want to post something exclusively to a forum (e.g. the support forum) pl
So !helpers will be an exclusive posting to the support forum if you are connected with the forum.
If you select a forum from the ACL a !-mention will be added automatically to your posting.
If you sort your contacts into groups, you cannot @-mention these groups.
But you can select the group in the access control when creating a new posting, to allow (or disallow) a certain group of people to see the posting.
See [Groups and Privacy](help/Groups-and-Privacy) for more details about grouping your contacts.
If you sort your contacts into circles, you cannot @-mention these circles.
But you can select the circle in the access control when creating a new posting, to allow (or disallow) a certain circle of people to see the posting.
See [Circles and Privacy](help/Circles-and-Privacy) for more details about grouping your contacts.
**Topical Tags**

View file

@ -88,11 +88,11 @@ Click on "show" under contact name to hide the post to everyone but selected.
Click on "Visible to everybody" to make the post public again.
If you have defined some groups, you can check "show" for groups also. All contact in that group will see the post.
If you want to hide the post to one contact of a group selected for "show", click "don't show" under contact name.
If you have defined some circles, you can check "show" for circles also. All contact in that circle will see the post.
If you want to hide the post to one contact of a circle selected for "show", click "don't show" under contact name.
Click again on "show" or "don't show" to switch it off.
You can search for contacts or groups with the search box.
You can search for contacts or circles with the search box.
See also [Group and Privacy](help/Groups-and-Privacy)
See also [Circles and Privacy](help/Circles-and-Privacy)

View file

@ -68,8 +68,8 @@ xml:
The [RSStoFriendika](https://github.com/pafcu/RSStoFriendika) code can be used as an example of how to use the API with python.
The lines for posting are located at [line 21](https://github.com/pafcu/RSStoFriendika/blob/master/RSStoFriendika.py#L21) and following.
def tweet(server, message, group_allow=None):
def tweet(server, message, circle_allow=None):
url = server + '/api/statuses/update'
urllib2.urlopen(url, urllib.urlencode({'status': message,'group_allow[]':group_allow}, doseq=True))
urllib2.urlopen(url, urllib.urlencode({'status': message, 'circle_allow[]': circle_allow}, doseq=True))
There is also a [module for python 3](https://bitbucket.org/tobiasd/python-friendica) for using the API.

View file

@ -30,8 +30,8 @@ Database Tables
| [fetch-entry](help/database/db_fetch-entry) | |
| [fetched-activity](help/database/db_fetched-activity) | Id of fetched activities |
| [fsuggest](help/database/db_fsuggest) | friend suggestion stuff |
| [group](help/database/db_group) | privacy groups, group info |
| [group_member](help/database/db_group_member) | privacy groups, member info |
| [group](help/database/db_group) | privacy circles, circle info |
| [group_member](help/database/db_group_member) | privacy circles, member info |
| [gserver](help/database/db_gserver) | Global servers |
| [gserver-tag](help/database/db_gserver-tag) | Tags that the server has subscribed |
| [hook](help/database/db_hook) | addon hook registry |

View file

@ -18,9 +18,9 @@ Fields
| created | creation time | datetime | NO | | 0001-01-01 00:00:00 | |
| edited | last edit time | datetime | NO | | 0001-01-01 00:00:00 | |
| allow_cid | Access Control - list of allowed contact.id '<19><78> | mediumtext | YES | | NULL | |
| allow_gid | Access Control - list of allowed groups | mediumtext | YES | | NULL | |
| allow_gid | Access Control - list of allowed circles | mediumtext | YES | | NULL | |
| deny_cid | Access Control - list of denied contact.id | mediumtext | YES | | NULL | |
| deny_gid | Access Control - list of denied groups | mediumtext | YES | | NULL | |
| deny_gid | Access Control - list of denied circles | mediumtext | YES | | NULL | |
| backend-class | Storage backend class | tinytext | YES | | NULL | |
| backend-ref | Storage backend data reference | text | YES | | NULL | |

View file

@ -25,9 +25,9 @@ Fields
| nofinish | if event does have no end this is 1 | boolean | NO | | 0 | |
| ignore | 0 or 1 | boolean | NO | | 0 | |
| allow_cid | Access Control - list of allowed contact.id '<19><78>' | mediumtext | YES | | NULL | |
| allow_gid | Access Control - list of allowed groups | mediumtext | YES | | NULL | |
| allow_gid | Access Control - list of allowed circles | mediumtext | YES | | NULL | |
| deny_cid | Access Control - list of denied contact.id | mediumtext | YES | | NULL | |
| deny_gid | Access Control - list of denied groups | mediumtext | YES | | NULL | |
| deny_gid | Access Control - list of denied circles | mediumtext | YES | | NULL | |
Indexes
------------

View file

@ -1,7 +1,7 @@
Table group
===========
privacy groups, group info
privacy circles, circle info
Fields
------
@ -11,9 +11,9 @@ Fields
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
| uid | Owner User id | mediumint unsigned | NO | | 0 | |
| visible | 1 indicates the member list is not private | boolean | NO | | 0 | |
| deleted | 1 indicates the group has been deleted | boolean | NO | | 0 | |
| deleted | 1 indicates the circle has been deleted | boolean | NO | | 0 | |
| cid | Contact id of forum. When this field is filled then the members are synced automatically. | int unsigned | YES | | NULL | |
| name | human readable name of group | varchar(255) | NO | | | |
| name | human readable name of circle | varchar(255) | NO | | | |
Indexes
------------

View file

@ -1,16 +1,16 @@
Table group_member
===========
privacy groups, member info
privacy circles, member info
Fields
------
| Field | Description | Type | Null | Key | Default | Extra |
| ---------- | --------------------------------------------------------- | ------------ | ---- | --- | ------- | -------------- |
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
| gid | groups.id of the associated group | int unsigned | NO | | 0 | |
| contact-id | contact.id of the member assigned to the associated group | int unsigned | NO | | 0 | |
| Field | Description | Type | Null | Key | Default | Extra |
| ---------- | ---------------------------------------------------------- | ------------ | ---- | --- | ------- | -------------- |
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
| gid | group.id of the associated circle | int unsigned | NO | | 0 | |
| contact-id | contact.id of the member assigned to the associated circle | int unsigned | NO | | 0 | |
Indexes
------------

View file

@ -11,9 +11,9 @@ Fields
| id | sequential ID | int unsigned | NO | PRI | NULL | auto_increment |
| uid | Owner id of this permission set | mediumint unsigned | NO | | 0 | |
| allow_cid | Access Control - list of allowed contact.id '<19><78>' | mediumtext | YES | | NULL | |
| allow_gid | Access Control - list of allowed groups | mediumtext | YES | | NULL | |
| allow_gid | Access Control - list of allowed circles | mediumtext | YES | | NULL | |
| deny_cid | Access Control - list of denied contact.id | mediumtext | YES | | NULL | |
| deny_gid | Access Control - list of denied groups | mediumtext | YES | | NULL | |
| deny_gid | Access Control - list of denied circles | mediumtext | YES | | NULL | |
Indexes
------------

View file

@ -30,9 +30,9 @@ Fields
| scale | | tinyint unsigned | NO | | 0 | |
| profile | | boolean | NO | | 0 | |
| allow_cid | Access Control - list of allowed contact.id '<19><78>' | mediumtext | YES | | NULL | |
| allow_gid | Access Control - list of allowed groups | mediumtext | YES | | NULL | |
| allow_gid | Access Control - list of allowed circles | mediumtext | YES | | NULL | |
| deny_cid | Access Control - list of denied contact.id | mediumtext | YES | | NULL | |
| deny_gid | Access Control - list of denied groups | mediumtext | YES | | NULL | |
| deny_gid | Access Control - list of denied circles | mediumtext | YES | | NULL | |
| accessible | Make photo publicly accessible, ignoring permissions | boolean | NO | | 0 | |
| backend-class | Storage backend class | tinytext | YES | | NULL | |
| backend-ref | Storage backend data reference | text | YES | | NULL | |

View file

@ -109,7 +109,7 @@ Ein ['Tipp für neue Mitglieder'](newmember)-Link zeigt sich in den ersten beide
## Schau Dir ebenfalls folgende Seiten an
* [Gruppen und Privatssphäre](help/Groups-and-Privacy)
* [Circles und Privatssphäre](help/Circles-and-Privacy)
* [Account löschen](help/Remove-Account)

View file

@ -1,54 +1,54 @@
Gruppen und Privatsphäre
Circles und Privatsphäre
==================
* [Zur Startseite der Hilfe](help)
Gruppen sind nur eine Ansammlung von Freunden.
Circles sind nur eine Ansammlung von Freunden.
Aber Friendica nutzt diese, um sehr mächtige Features zur Verfügung zu stellen.
**Gruppen erstellen**
**Circles erstellen**
Um eine Gruppe zu erstellen, besuche deine "Kontakte"-Seite und wähle "Neue Gruppe erstellen" (je nach Design nur als Pluszeichen angezeigt).
Gib deiner Gruppe einen Namen.
Um eine Circle zu erstellen, besuche deine "Kontakte"-Seite und wähle "Neue Circle erstellen" (je nach Design nur als Pluszeichen angezeigt).
Gib deiner Circle einen Namen.
Das führt dich zu einer Seite, auf der du die Gruppenmitglieder auswählen kannst.
Du hast zwei Boxen auf der Seite.
Die obere Box ist die Übersicht der aktuellen Mitglieder.
Die untere beinhaltet alle Freunde, die *nicht* Mitglied dieser Gruppe sind.
Die untere beinhaltet alle Freunde, die *nicht* Mitglied dieser Circle sind.
Wenn du auf das Foto einer Person klickst, die nicht in der Gruppe ist, wird diese in die Gruppe verschoben.
Wenn du auf das Foto einer Person klickst, die bereits in der Gruppe ist, dann wird diese Person daraus entfernt.
Wenn du auf das Foto einer Person klickst, die nicht in der Circle ist, wird diese in die Circle verschoben.
Wenn du auf das Foto einer Person klickst, die bereits in der Circle ist, dann wird diese Person daraus entfernt.
**Zugriffskontrolle**
Sobald du eine Gruppe erstellt hast, kannst du diese auf jeder Zugriffsrechteliste nutzen.
Sobald du eine Circle erstellt hast, kannst du diese auf jeder Zugriffsrechteliste nutzen.
Damit ist das kleine Schloss neben deinem Statuseditor auf deiner Startseite gemeint.
Wenn du darauf klickst, kannst du auswählen, wer deinen Beitrag sehen kann und wer *nicht*.
Dabei kann es sich um eine einzelne Person oder eine ganze Gruppe handeln.
Dabei kann es sich um eine einzelne Person oder eine ganze Circle handeln.
Auf deiner "Netzwerk"-Seite ("Unterhaltungen deiner Kontakte") findest du Beiträge und Gespräche aller deiner Kontakte in deinem Netzwerk.
Du kannst aber auch eine einzelne Gruppe auswählen und nur Beiträge dieser Gruppenmitglieder anzeigen lassen.
Du kannst aber auch eine einzelne Circle auswählen und nur Beiträge dieser Gruppenmitglieder anzeigen lassen.
Aber stopp, es gibt noch mehr...
Wenn du auf deiner "Netzwerk"-Seite eine bestimmte Gruppe ausgewählt hast, dann findest du im Statuseditor neben dem Schloss ein Ausrufezeichen.
Wenn du auf deiner "Netzwerk"-Seite eine bestimmte Circle ausgewählt hast, dann findest du im Statuseditor neben dem Schloss ein Ausrufezeichen.
Dies dient dazu, deine Aufmerksamkeit auf das Schloss zu richten.
Klicke auf das Schloss.
Dort siehst du, dass dein Status-Update in dieser Ansicht standardmäßig nur für diese Gruppe freigegeben ist.
Dort siehst du, dass dein Status-Update in dieser Ansicht standardmäßig nur für diese Circle freigegeben ist.
Das hilft dir, deinen zukünftigen Mitarbeitern nicht das Gleiche zu schreiben wie deinen Trinkfreunden.
Du kannst diese Einstellung natürlich auch überschreiben.
**Standardmäßige Zugriffsrechte von Beiträgen**
Standardmäßig geht Friendica davon aus, dass alle deine Beiträge privat sein sollen.
Aus diesem Grund erstellt Friendica nach der Anmeldung eine Gruppe, in die automatisch alle deine Kontakte hinzugefügt werden.
Alle deine Beiträge sind nur auf diese Gruppe beschränkt.
Aus diesem Grund erstellt Friendica nach der Anmeldung eine Circle, in die automatisch alle deine Kontakte hinzugefügt werden.
Alle deine Beiträge sind nur auf diese Circle beschränkt.
Beachte, dass diese Einstellung von deinem Seiten-Administrator überschrieben werden kann, was bedeutet, dass alle deine Beiträge standardmäßig "öffentlich" sind (bspw. für das gesamte Internet).
Wenn du deine Beiträge standardmäßig "öffentlich" haben willst, dann kannst du deine Standardzugriffsrechte auf deiner Einstellungseite ändern.
Dort kannst du außerdem festlegen, welchen Gruppen standardmäßig deine Beiträge erhalten oder in welche Gruppe deine neuen Kontakte standardmäßig eingeordnet werden.
Dort kannst du außerdem festlegen, welchen Circles standardmäßig deine Beiträge erhalten oder in welche Circle deine neuen Kontakte standardmäßig eingeordnet werden.
**Fragen der Privatssphäre, die zu beachten sind**
@ -60,7 +60,7 @@ Keine Software der Welt kann deine Freunde davon abhalten, die privaten Unterhal
Nur eine gute Auswahl deiner Freunde.
Bei GNu Social und anderen Netzwerk-Anbietern ist es nicht so gesichert.
Du musst **sehr** vorsichtig sein, wenn du Mitglieder anderer Netzwerke in einer deiner Gruppen hast, da es möglich ist, dass deine privaten Nachrichten in einem öffentlichen Stream enden.
Du musst **sehr** vorsichtig sein, wenn du Mitglieder anderer Netzwerke in einer deiner Circles hast, da es möglich ist, dass deine privaten Nachrichten in einem öffentlichen Stream enden.
Wenn du auf die "Kontakt bearbeiten"-Seite einer Person gehst, zeigen wir dir, ob sie Mitglied eines unsicheren Netzwerks ist oder nicht.
Sobald du einen Post erstellt hast, kannst du die Zugriffsrechte nicht mehr ändern.

View file

@ -14,7 +14,7 @@ Friendica - Dokumentation und Ressourcen
* Du und andere Nutzer
* [Konnektoren (Connectors)](help/Connectors)
* [Freunde finden](help/Making-Friends)
* [Gruppen und Privatsphäre](help/Groups-and-Privacy)
* [Circles und Privatsphäre](help/Circles-and-Privacy)
* [Tags und Erwähnungen](help/Tags-and-Mentions)
* [Community-Foren](help/Forums)
* [Chats](help/Chats)

View file

@ -27,7 +27,7 @@ Diese Maßnahme dient dazu, Spam zu vermeiden.
"Fernerwähnungen" werden durch das OStatus-Protokoll übermittelt.
Dieses Protokoll wird von Friendica, GNU Social und anderen Systemen genutzt, ist allerdings derzeit nicht in Diaspora eingebaut.
Friendica unterscheidet bei Tags nicht zwischen Personen und Gruppen (einige andere Netzwerke nutzen "!gruppe", um solche zu markieren).
Friendica unterscheidet bei Tags nicht zwischen Personen und Gruppen (einige andere Netzwerke nutzen "!circle", um solche zu markieren).
**Thematische Tags**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 598 B

View file

Before

Width:  |  Height:  |  Size: 543 B

After

Width:  |  Height:  |  Size: 543 B

View file

Before

Width:  |  Height:  |  Size: 852 B

After

Width:  |  Height:  |  Size: 852 B

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -1,6 +1,6 @@
IMAGES=add.png edit.png gear.png info.png menu.png \
notify_off.png star.png delete.png feed.png group.png \
notify_off.png star.png delete.png feed.png circle.png \
lock.png notice.png notify_on.png user.png link.png \
play.png plugin.png unlock.png zip.png audio.png video.png \
image.png text.png

View file

Before

Width:  |  Height:  |  Size: 7 KiB

After

Width:  |  Height:  |  Size: 7 KiB

View file

@ -163,14 +163,14 @@ function photos_post(App $a)
$aclFormatter = DI::aclFormatter();
$str_contact_allow = isset($_REQUEST['contact_allow']) ? $aclFormatter->toString($_REQUEST['contact_allow']) : $owner_record['allow_cid'] ?? '';
$str_group_allow = isset($_REQUEST['group_allow']) ? $aclFormatter->toString($_REQUEST['group_allow']) : $owner_record['allow_gid'] ?? '';
$str_circle_allow = isset($_REQUEST['circle_allow']) ? $aclFormatter->toString($_REQUEST['circle_allow']) : $owner_record['allow_gid'] ?? '';
$str_contact_deny = isset($_REQUEST['contact_deny']) ? $aclFormatter->toString($_REQUEST['contact_deny']) : $owner_record['deny_cid'] ?? '';
$str_group_deny = isset($_REQUEST['group_deny']) ? $aclFormatter->toString($_REQUEST['group_deny']) : $owner_record['deny_gid'] ?? '';
$str_circle_deny = isset($_REQUEST['circle_deny']) ? $aclFormatter->toString($_REQUEST['circle_deny']) : $owner_record['deny_gid'] ?? '';
$visibility = $_REQUEST['visibility'] ?? '';
if ($visibility === 'public') {
// The ACL selector introduced in version 2019.12 sends ACL input data even when the Public visibility is selected
$str_contact_allow = $str_group_allow = $str_contact_deny = $str_group_deny = '';
$str_contact_allow = $str_circle_allow = $str_contact_deny = $str_circle_deny = '';
} else if ($visibility === 'custom') {
// Since we know from the visibility parameter the item should be private, we have to prevent the empty ACL
// case that would make it public. So we always append the author's contact id to the allowed contacts.
@ -338,7 +338,7 @@ function photos_post(App $a)
$photo = $photos[0];
$ext = $phototypes[$photo['type']];
Photo::update(
['desc' => $desc, 'album' => $albname, 'allow_cid' => $str_contact_allow, 'allow_gid' => $str_group_allow, 'deny_cid' => $str_contact_deny, 'deny_gid' => $str_group_deny],
['desc' => $desc, 'album' => $albname, 'allow_cid' => $str_contact_allow, 'allow_gid' => $str_circle_allow, 'deny_cid' => $str_contact_deny, 'deny_gid' => $str_circle_deny],
['resource-id' => $resource_id, 'uid' => $page_owner_uid]
);

View file

@ -38,7 +38,7 @@ use Friendica\Model\Attach;
use Friendica\Model\Contact;
use Friendica\Model\Conversation;
use Friendica\Model\FileTag;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Model\Item as ItemModel;
use Friendica\Model\Photo;
use Friendica\Model\Tag;
@ -542,7 +542,7 @@ class Item
if ($private_forum) {
$item['allow_cid'] = '<' . $private_id . '>';
$item['allow_gid'] = '<' . Group::getIdForForum($forum_contact['id']) . '>';
$item['allow_gid'] = '<' . Circle::getIdForForum($forum_contact['id']) . '>';
} else {
$item['allow_cid'] = '';
$item['allow_gid'] = '';
@ -863,9 +863,9 @@ class Item
}
$post['allow_cid'] = isset($request['contact_allow']) ? $this->aclFormatter->toString($request['contact_allow']) : $user['allow_cid'] ?? '';
$post['allow_gid'] = isset($request['group_allow']) ? $this->aclFormatter->toString($request['group_allow']) : $user['allow_gid'] ?? '';
$post['allow_gid'] = isset($request['circle_allow']) ? $this->aclFormatter->toString($request['circle_allow']) : $user['allow_gid'] ?? '';
$post['deny_cid'] = isset($request['contact_deny']) ? $this->aclFormatter->toString($request['contact_deny']) : $user['deny_cid'] ?? '';
$post['deny_gid'] = isset($request['group_deny']) ? $this->aclFormatter->toString($request['group_deny']) : $user['deny_gid'] ?? '';
$post['deny_gid'] = isset($request['circle_deny']) ? $this->aclFormatter->toString($request['circle_deny']) : $user['deny_gid'] ?? '';
$visibility = $request['visibility'] ?? '';
if ($visibility === 'public') {

View file

@ -531,7 +531,7 @@ class HTML
$ignore = false;
// A list of some links that should be ignored
$list = ["/user/", "/tag/", "/group/", "/profile/", "/search?search=", "/search?tag=", "mailto:", "/u/", "/node/",
$list = ["/user/", "/tag/", "/group/", "/circle/", "/profile/", "/search?search=", "/search?tag=", "mailto:", "/u/", "/node/",
"//plus.google.com/", "//twitter.com/"];
foreach ($list as $listitem) {
if (strpos($treffer[1], $listitem) !== false) {

View file

@ -29,7 +29,7 @@ use Friendica\Core\Search;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Model\Item;
use Friendica\Model\Post;
use Friendica\Model\Profile;
@ -194,29 +194,29 @@ class Widget
}
/**
* Return group membership widget
* Return circle membership widget
*
* @param string $baseurl
* @param string $selected
* @return string
* @throws \Exception
*/
public static function groups(string $baseurl, string $selected = ''): string
public static function circles(string $baseurl, string $selected = ''): string
{
if (!DI::userSession()->getLocalUserId()) {
return '';
}
$options = array_map(function ($group) {
$options = array_map(function ($circle) {
return [
'ref' => $group['id'],
'name' => $group['name']
'ref' => $circle['id'],
'name' => $circle['name']
];
}, Group::getByUserId(DI::userSession()->getLocalUserId()));
}, Circle::getByUserId(DI::userSession()->getLocalUserId()));
return self::filter(
'group',
DI::l10n()->t('Groups'),
'circle',
DI::l10n()->t('Circles'),
'',
DI::l10n()->t('Everyone'),
$baseurl,

View file

@ -25,7 +25,7 @@ use Friendica\App\Page;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Model\User;
/**
@ -182,40 +182,40 @@ class ACL
}
/**
* Returns the ACL list of groups (including meta-groups) for a given user id
* Returns the ACL list of circles (including meta-circles) for a given user id
*
* @param int $user_id
* @return array
*/
public static function getGroupListByUserId(int $user_id)
public static function getCircleListByUserId(int $user_id)
{
$acl_groups = [
$acl_circles = [
[
'id' => Group::FOLLOWERS,
'id' => Circle::FOLLOWERS,
'name' => DI::l10n()->t('Followers'),
'addr' => '',
'micro' => 'images/twopeople.png',
'type' => 'group',
'type' => 'circle',
],
[
'id' => Group::MUTUALS,
'id' => Circle::MUTUALS,
'name' => DI::l10n()->t('Mutuals'),
'addr' => '',
'micro' => 'images/twopeople.png',
'type' => 'group',
'type' => 'circle',
]
];
foreach (Group::getByUserId($user_id) as $group) {
$acl_groups[] = [
'id' => $group['id'],
'name' => $group['name'],
foreach (Circle::getByUserId($user_id) as $circle) {
$acl_circles[] = [
'id' => $circle['id'],
'name' => $circle['name'],
'addr' => '',
'micro' => 'images/twopeople.png',
'type' => 'group',
'type' => 'circle',
];
}
return $acl_groups;
return $acl_circles;
}
/**
@ -279,7 +279,7 @@ class ACL
} else {
$visibility = 'public';
// Default permission display for custom panel
$default_permissions['allow_gid'] = [Group::FOLLOWERS];
$default_permissions['allow_gid'] = [Circle::FOLLOWERS];
}
$jotnets_fields = [];
@ -303,15 +303,15 @@ class ACL
$acl_contacts = self::getContactListByUserId($user['uid'], $condition);
$acl_groups = self::getGroupListByUserId($user['uid']);
$acl_circles = self::getCircleListByUserId($user['uid']);
$acl_list = array_merge($acl_groups, $acl_contacts);
$acl_list = array_merge($acl_circles, $acl_contacts);
$input_names = [
'visibility' => $form_prefix ? $form_prefix . '[visibility]' : 'visibility',
'group_allow' => $form_prefix ? $form_prefix . '[group_allow]' : 'group_allow',
'circle_allow' => $form_prefix ? $form_prefix . '[circle_allow]' : 'circle_allow',
'contact_allow' => $form_prefix ? $form_prefix . '[contact_allow]' : 'contact_allow',
'group_deny' => $form_prefix ? $form_prefix . '[group_deny]' : 'group_deny',
'circle_deny' => $form_prefix ? $form_prefix . '[circle_deny]' : 'circle_deny',
'contact_deny' => $form_prefix ? $form_prefix . '[contact_deny]' : 'contact_deny',
'emailcc' => $form_prefix ? $form_prefix . '[emailcc]' : 'emailcc',
];
@ -321,7 +321,7 @@ class ACL
'$public_title' => DI::l10n()->t('Public'),
'$public_desc' => DI::l10n()->t('This content will be shown to all your followers and can be seen in the community pages and by anyone with its link.'),
'$custom_title' => DI::l10n()->t('Limited/Private'),
'$custom_desc' => DI::l10n()->t('This content will be shown only to the people in the first box, to the exception of the people mentioned in the second box. It won\'t appear anywhere public.') . DI::l10n()->t('Start typing the name of a contact or a group to show a filtered list. You can also mention the special groups "Followers" and "Mutuals".'),
'$custom_desc' => DI::l10n()->t('This content will be shown only to the people in the first box, to the exception of the people mentioned in the second box. It won\'t appear anywhere public.') . DI::l10n()->t('Start typing the name of a contact or a circle to show a filtered list. You can also mention the special circles "Followers" and "Mutuals".'),
'$allow_label' => DI::l10n()->t('Show to:'),
'$deny_label' => DI::l10n()->t('Except to:'),
'$emailcc' => DI::l10n()->t('CC: email addresses'),
@ -329,12 +329,12 @@ class ACL
'$jotnets_summary' => DI::l10n()->t('Connectors'),
'$visibility' => $visibility,
'$acl_contacts' => json_encode($acl_contacts),
'$acl_groups' => json_encode($acl_groups),
'$acl_circles' => json_encode($acl_circles),
'$acl_list' => json_encode($acl_list),
'$contact_allow' => implode(',', $default_permissions['allow_cid']),
'$group_allow' => implode(',', $default_permissions['allow_gid']),
'$circle_allow' => implode(',', $default_permissions['allow_gid']),
'$contact_deny' => implode(',', $default_permissions['deny_cid']),
'$group_deny' => implode(',', $default_permissions['deny_gid']),
'$circle_deny' => implode(',', $default_permissions['deny_gid']),
'$for_federation' => $for_federation,
'$jotnets_fields' => $jotnets_fields,
'$input_names' => $input_names,
@ -381,7 +381,7 @@ class ACL
* @return bool
* @throws Exception
*/
public static function isValidGroup($acl_string, $uid)
public static function isValidCircle($acl_string, $uid)
{
if (empty($acl_string)) {
return true;
@ -394,7 +394,7 @@ class ACL
$gid_array = $array[0];
foreach ($gid_array as $gid) {
$gid = str_replace(['<', '>'], ['', ''], $gid);
if (!DBA::exists('group', ['id' => $gid, 'uid' => $uid, 'deleted' => false])) {
if (!DBA::exists('circle', ['id' => $gid, 'uid' => $uid, 'deleted' => false])) {
return false;
}
}

View file

@ -27,7 +27,7 @@ use Friendica\Network\HTTPException;
use Psr\Log\LoggerInterface;
use Friendica\Factory\Api\Twitter\User as TwitterUser;
class Group extends BaseFactory
class Circle extends BaseFactory
{
/** @var twitterUser entity */
private $twitterUser;
@ -43,19 +43,19 @@ class Group extends BaseFactory
}
/**
* @param int $id id of the group
* @param int $id id of the circle
* @return array
* @throws HTTPException\InternalServerErrorException
*/
public function createFromId(int $id): array
{
$group = $this->dba->selectFirst('group', [], ['id' => $id, 'deleted' => false]);
if (empty($group)) {
$circle = $this->dba->selectFirst('group', [], ['id' => $id, 'deleted' => false]);
if (empty($circle)) {
return [];
}
$user = $this->twitterUser->createFromUserId($group['uid'])->toArray();
$object = new \Friendica\Object\Api\Friendica\Group($group, $user);
$user = $this->twitterUser->createFromUserId($circle['uid'])->toArray();
$object = new \Friendica\Object\Api\Friendica\Circle($circle, $user);
return $object->toArray();
}

View file

@ -40,9 +40,9 @@ class ListEntity extends BaseFactory
/**
* @throws InternalServerErrorException
*/
public function createFromGroupId(int $id): \Friendica\Object\Api\Mastodon\ListEntity
public function createFromCircleId(int $id): \Friendica\Object\Api\Mastodon\ListEntity
{
$group = $this->dba->selectFirst('group', ['name'], ['id' => $id, 'deleted' => false]);
return new \Friendica\Object\Api\Mastodon\ListEntity($id, $group['name'] ?? '', 'list');
$circle = $this->dba->selectFirst('group', ['name'], ['id' => $id, 'deleted' => false]);
return new \Friendica\Object\Api\Mastodon\ListEntity($id, $circle['name'] ?? '', 'list');
}
}

View file

@ -190,9 +190,9 @@ class Attach
* @param string $filetype Mimetype. optional, default = ''
* @param integer $filesize File size in bytes. optional, default = null
* @param string $allow_cid Permissions, allowed contacts. optional, default = ''
* @param string $allow_gid Permissions, allowed groups. optional, default = ''
* @param string $deny_cid Permissions, denied contacts.optional, default = ''
* @param string $deny_gid Permissions, denied group.optional, default = ''
* @param string $allow_gid Permissions, allowed circles. optional, default = ''
* @param string $deny_cid Permissions, denied contacts. optional, default = ''
* @param string $deny_gid Permissions, denied circle. optional, default = ''
*
* @return boolean|integer Row id on success, False on errors
* @throws \Friendica\Network\HTTPException\InternalServerErrorException

View file

@ -34,16 +34,16 @@ use Friendica\Protocol\ActivityPub;
/**
* functions for interacting with the group database table
*/
class Group
class Circle
{
const FOLLOWERS = '~';
const MUTUALS = '&';
/**
* Fetches group record by user id and maybe includes deleted groups as well
* Fetches circle record by user id and maybe includes deleted circles as well
*
* @param int $uid User id to fetch group(s) for
* @param bool $includesDeleted Whether deleted groups should be included
* @param int $uid User id to fetch circle(s) for
* @param bool $includesDeleted Whether deleted circles should be included
* @return array|bool Array on success, bool on error
*/
public static function getByUserId(int $uid, bool $includesDeleted = false)
@ -58,16 +58,16 @@ class Group
}
/**
* Checks whether given group id is found in database
* Checks whether given circle id is found in database
*
* @param int $group_id Group id
* @param int $circle_id Circle id
* @param int $uid Optional user id
* @return bool
* @throws \Exception
*/
public static function exists(int $group_id, int $uid = null): bool
public static function exists(int $circle_id, int $uid = null): bool
{
$condition = ['id' => $group_id, 'deleted' => false];
$condition = ['id' => $circle_id, 'deleted' => false];
if (!is_null($uid)) {
$condition = [
@ -79,13 +79,13 @@ class Group
}
/**
* Create a new contact group
* Create a new contact circle
*
* Note: If we found a deleted group with the same name, we restore it
* Note: If we found a deleted circle with the same name, we restore it
*
* @param int $uid User id to create group for
* @param string $name Name of group
* @return int|boolean Id of newly created group or false on error
* @param int $uid User id to create circle for
* @param string $name Name of circle
* @return int|boolean Id of newly created circle or false on error
* @throws \Exception
*/
public static function create(int $uid, string $name)
@ -95,14 +95,14 @@ class Group
$gid = self::getIdByName($uid, $name); // check for dupes
if ($gid !== false) {
// This could be a problem.
// Let's assume we've just created a group which we once deleted
// all the old members are gone, but the group remains so we don't break any security
// access lists. What we're doing here is reviving the dead group, but old content which
// was restricted to this group may now be seen by the new group members.
$group = DBA::selectFirst('group', ['deleted'], ['id' => $gid]);
if (DBA::isResult($group) && $group['deleted']) {
// Let's assume we've just created a circle which we once deleted
// all the old members are gone, but the circle remains, so we don't break any security
// access lists. What we're doing here is reviving the dead circle, but old content which
// was restricted to this circle may now be seen by the new circle members.
$circle = DBA::selectFirst('group', ['deleted'], ['id' => $gid]);
if (DBA::isResult($circle) && $circle['deleted']) {
DBA::update('group', ['deleted' => 0], ['id' => $gid]);
DI::sysmsg()->addNotice(DI::l10n()->t('A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name.'));
DI::sysmsg()->addNotice(DI::l10n()->t('A deleted circle with this name was revived. Existing item permissions <strong>may</strong> apply to this circle and any future members. If this is not what you intended, please create another circle with a different name.'));
}
return true;
}
@ -116,10 +116,10 @@ class Group
}
/**
* Update group information.
* Update circle information.
*
* @param int $id Group ID
* @param string $name Group name
* @param int $id Circle ID
* @param string $name Circle name
*
* @return bool Was the update successful?
* @throws \Exception
@ -130,10 +130,10 @@ class Group
}
/**
* Get a list of group ids a contact belongs to
* Get a list of circle ids a contact belongs to
*
* @param int $cid Contact id
* @return array Group ids
* @return array Circle ids
* @throws \Exception
*/
public static function getIdsByContactId(int $cid): array
@ -143,50 +143,50 @@ class Group
return [];
}
$groupIds = [];
$circleIds = [];
$stmt = DBA::select('group_member', ['gid'], ['contact-id' => $cid]);
while ($group = DBA::fetch($stmt)) {
$groupIds[] = $group['gid'];
while ($circle = DBA::fetch($stmt)) {
$circleIds[] = $circle['gid'];
}
DBA::close($stmt);
// Meta-groups
// Meta-circles
if ($contact['rel'] == Contact::FOLLOWER || $contact['rel'] == Contact::FRIEND) {
$groupIds[] = self::FOLLOWERS;
$circleIds[] = self::FOLLOWERS;
}
if ($contact['rel'] == Contact::FRIEND) {
$groupIds[] = self::MUTUALS;
$circleIds[] = self::MUTUALS;
}
return $groupIds;
return $circleIds;
}
/**
* count unread group items
* count unread circle items
*
* Count unread items of each groups of the local user
* Count unread items of each circle of the local user
*
* @return array
* 'id' => group id
* 'name' => group name
* 'count' => counted unseen group items
* 'id' => circle id
* 'name' => circle name
* 'count' => counted unseen circle items
* @throws \Exception
*/
public static function countUnseen()
{
$stmt = DBA::p("SELECT `group`.`id`, `group`.`name`,
$stmt = DBA::p("SELECT `circle`.`id`, `circle`.`name`,
(SELECT COUNT(*) FROM `post-user`
WHERE `uid` = ?
AND `unseen`
AND `contact-id` IN
(SELECT `contact-id`
FROM `group_member`
WHERE `group_member`.`gid` = `group`.`id`)
FROM `group_member` AS `circle_member`
WHERE `circle_member`.`gid` = `circle`.`id`)
) AS `count`
FROM `group`
WHERE `group`.`uid` = ?;",
FROM `group` AS `circle`
WHERE `circle`.`uid` = ?;",
DI::userSession()->getLocalUserId(),
DI::userSession()->getLocalUserId()
);
@ -195,13 +195,13 @@ class Group
}
/**
* Get the group id for a user/name couple
* Get the circle id for a user/name couple
*
* Returns false if no group has been found.
* Returns false if no circle has been found.
*
* @param int $uid User id
* @param string $name Group name
* @return int|boolean Groups' id number or false on error
* @param string $name Circle name
* @return int|boolean Circle's id number or false on error
* @throws \Exception
*/
public static function getIdByName(int $uid, string $name)
@ -210,16 +210,16 @@ class Group
return false;
}
$group = DBA::selectFirst('group', ['id'], ['uid' => $uid, 'name' => $name]);
if (DBA::isResult($group)) {
return $group['id'];
$circle = DBA::selectFirst('group', ['id'], ['uid' => $uid, 'name' => $name]);
if (DBA::isResult($circle)) {
return $circle['id'];
}
return false;
}
/**
* Mark a group as deleted
* Mark a circle as deleted
*
* @param int $gid
* @return boolean
@ -231,13 +231,13 @@ class Group
return false;
}
$group = DBA::selectFirst('group', ['uid'], ['id' => $gid]);
if (!DBA::isResult($group)) {
$circle = DBA::selectFirst('group', ['uid'], ['id' => $gid]);
if (!DBA::isResult($circle)) {
return false;
}
// remove group from default posting lists
$user = DBA::selectFirst('user', ['def_gid', 'allow_gid', 'deny_gid'], ['uid' => $group['uid']]);
// remove circle from default posting lists
$user = DBA::selectFirst('user', ['def_gid', 'allow_gid', 'deny_gid'], ['uid' => $circle['uid']]);
if (DBA::isResult($user)) {
$change = false;
@ -255,21 +255,21 @@ class Group
}
if ($change) {
DBA::update('user', $user, ['uid' => $group['uid']]);
DBA::update('user', $user, ['uid' => $circle['uid']]);
}
}
// remove all members
DBA::delete('group_member', ['gid' => $gid]);
// remove group
// remove circle
$return = DBA::update('group', ['deleted' => 1], ['id' => $gid]);
return $return;
}
/**
* Adds a contact to a group
* Adds a contact to a circle
*
* @param int $gid
* @param int $cid
@ -283,12 +283,12 @@ class Group
}
// @TODO Backward compatibility with user contacts, remove by version 2022.03
$group = DBA::selectFirst('group', ['uid'], ['id' => $gid]);
if (empty($group)) {
throw new HTTPException\NotFoundException('Group not found.');
$circle = DBA::selectFirst('group', ['uid'], ['id' => $gid]);
if (empty($circle)) {
throw new HTTPException\NotFoundException('Circle not found.');
}
$cdata = Contact::getPublicAndUserContactID($cid, $group['uid']);
$cdata = Contact::getPublicAndUserContactID($cid, $circle['uid']);
if (empty($cdata['user'])) {
throw new HTTPException\NotFoundException('Invalid contact.');
}
@ -297,7 +297,7 @@ class Group
}
/**
* Removes a contact from a group
* Removes a contact from a circle
*
* @param int $gid
* @param int $cid
@ -311,12 +311,12 @@ class Group
}
// @TODO Backward compatibility with user contacts, remove by version 2022.03
$group = DBA::selectFirst('group', ['uid'], ['id' => $gid]);
if (empty($group)) {
throw new HTTPException\NotFoundException('Group not found.');
$circle = DBA::selectFirst('group', ['uid'], ['id' => $gid]);
if (empty($circle)) {
throw new HTTPException\NotFoundException('Circle not found.');
}
$cdata = Contact::getPublicAndUserContactID($cid, $group['uid']);
$cdata = Contact::getPublicAndUserContactID($cid, $circle['uid']);
if (empty($cdata['user'])) {
throw new HTTPException\NotFoundException('Invalid contact.');
}
@ -325,7 +325,7 @@ class Group
}
/**
* Adds contacts to a group
* Adds contacts to a circle
*
* @param int $gid
* @param array $contacts Array with contact ids
@ -339,13 +339,13 @@ class Group
}
// @TODO Backward compatibility with user contacts, remove by version 2022.03
$group = DBA::selectFirst('group', ['uid'], ['id' => $gid]);
if (empty($group)) {
throw new HTTPException\NotFoundException('Group not found.');
$circle = DBA::selectFirst('group', ['uid'], ['id' => $gid]);
if (empty($circle)) {
throw new HTTPException\NotFoundException('Circle not found.');
}
foreach ($contacts as $cid) {
$cdata = Contact::getPublicAndUserContactID($cid, $group['uid']);
$cdata = Contact::getPublicAndUserContactID($cid, $circle['uid']);
if (empty($cdata['user'])) {
throw new HTTPException\NotFoundException('Invalid contact.');
}
@ -355,9 +355,9 @@ class Group
}
/**
* Removes contacts from a group
* Removes contacts from a circle
*
* @param int $gid Group id
* @param int $gid Circle id
* @param array $contacts Contact ids
* @return bool
* @throws \Exception
@ -369,15 +369,15 @@ class Group
}
// @TODO Backward compatibility with user contacts, remove by version 2022.03
$group = DBA::selectFirst('group', ['uid'], ['id' => $gid]);
if (empty($group)) {
throw new HTTPException\NotFoundException('Group not found.');
$circle = DBA::selectFirst('group', ['uid'], ['id' => $gid]);
if (empty($circle)) {
throw new HTTPException\NotFoundException('Circle not found.');
}
$contactIds = [];
foreach ($contacts as $cid) {
$cdata = Contact::getPublicAndUserContactID($cid, $group['uid']);
$cdata = Contact::getPublicAndUserContactID($cid, $circle['uid']);
if (empty($cdata['user'])) {
throw new HTTPException\NotFoundException('Invalid contact.');
}
@ -390,18 +390,18 @@ class Group
}
/**
* Returns the combined list of contact ids from a group id list
* Returns the combined list of contact ids from a circle id list
*
* @param int $uid User id
* @param array $group_ids Groups ids
* @param array $circle_ids Circles ids
* @param boolean $check_dead Whether check "dead" records (?)
* @param boolean $expand_followers Expand the list of followers
* @return array
* @throws \Exception
*/
public static function expand(int $uid, array $group_ids, bool $check_dead = false, bool $expand_followers = true): array
public static function expand(int $uid, array $circle_ids, bool $check_dead = false, bool $expand_followers = true): array
{
if (!is_array($group_ids) || !count($group_ids)) {
if (!is_array($circle_ids) || !count($circle_ids)) {
return [];
}
@ -419,7 +419,7 @@ class Group
$networks = array_diff($networks, [Protocol::MAIL]);
}
$key = array_search(self::FOLLOWERS, $group_ids);
$key = array_search(self::FOLLOWERS, $circle_ids);
if ($key !== false) {
if ($expand_followers) {
$followers = Contact::selectToArray(['id'], [
@ -438,10 +438,10 @@ class Group
} else {
$followers_collection = true;
}
unset($group_ids[$key]);
unset($circle_ids[$key]);
}
$key = array_search(self::MUTUALS, $group_ids);
$key = array_search(self::MUTUALS, $circle_ids);
if ($key !== false) {
$mutuals = Contact::selectToArray(['id'], [
'uid' => $uid,
@ -457,12 +457,12 @@ class Group
$return[] = $mutual['id'];
}
unset($group_ids[$key]);
unset($circle_ids[$key]);
}
$stmt = DBA::select('group_member', ['contact-id'], ['gid' => $group_ids]);
while ($group_member = DBA::fetch($stmt)) {
$return[] = $group_member['contact-id'];
$stmt = DBA::select('group_member', ['contact-id'], ['gid' => $circle_ids]);
while ($circle_member = DBA::fetch($stmt)) {
$return[] = $circle_member['contact-id'];
}
DBA::close($stmt);
@ -478,17 +478,17 @@ class Group
}
/**
* Returns a templated group selection list
* Returns a templated circle selection list
*
* @param int $uid User id
* @param int $gid An optional pre-selected group
* @param int $gid An optional pre-selected circle
* @param string $label An optional label of the list
* @return string
* @throws \Exception
*/
public static function displayGroupSelection(int $uid, int $gid = 0, string $label = ''): string
public static function getSelectorHTML(int $uid, int $gid = 0, string $label = ''): string
{
$display_groups = [
$display_circles = [
[
'name' => '',
'id' => '0',
@ -497,53 +497,53 @@ class Group
];
$stmt = DBA::select('group', [], ['deleted' => false, 'uid' => $uid, 'cid' => null], ['order' => ['name']]);
while ($group = DBA::fetch($stmt)) {
$display_groups[] = [
'name' => $group['name'],
'id' => $group['id'],
'selected' => $gid == $group['id'] ? 'true' : ''
while ($circle = DBA::fetch($stmt)) {
$display_circles[] = [
'name' => $circle['name'],
'id' => $circle['id'],
'selected' => $gid == $circle['id'] ? 'true' : ''
];
}
DBA::close($stmt);
Logger::info('Got groups', $display_groups);
Logger::info('Got circles', $display_circles);
if ($label == '') {
$label = DI::l10n()->t('Default privacy group for new contacts');
$label = DI::l10n()->t('Default privacy circle for new contacts');
}
$o = Renderer::replaceMacros(Renderer::getMarkupTemplate('group_selection.tpl'), [
$o = Renderer::replaceMacros(Renderer::getMarkupTemplate('circle_selection.tpl'), [
'$label' => $label,
'$groups' => $display_groups
'$circles' => $display_circles
]);
return $o;
}
/**
* Create group sidebar widget
* Create circle sidebar widget
*
* @param string $every
* @param string $each
* @param string $editmode
* 'standard' => include link 'Edit groups'
* 'extended' => include link 'Create new group'
* 'full' => include link 'Create new group' and provide for each group a link to edit this group
* @param string|int $group_id Distinct group id or 'everyone'
* 'standard' => include link 'Edit circles'
* 'extended' => include link 'Create new circle'
* 'full' => include link 'Create new circle' and provide for each circle a link to edit this circle
* @param string|int $circle_id Distinct circle id or 'everyone'
* @param int $cid Contact id
* @return string Sidebar widget HTML code
* @throws \Exception
*/
public static function sidebarWidget(string $every = 'contact', string $each = 'group', string $editmode = 'standard', $group_id = '', int $cid = 0)
public static function sidebarWidget(string $every = 'contact', string $each = 'circle', string $editmode = 'standard', $circle_id = '', int $cid = 0)
{
if (!DI::userSession()->getLocalUserId()) {
return '';
}
$display_groups = [
$display_circles = [
[
'text' => DI::l10n()->t('Everybody'),
'id' => 0,
'selected' => (($group_id === 'everyone') ? 'group-selected' : ''),
'selected' => (($circle_id === 'everyone') ? 'circle-selected' : ''),
'href' => $every,
]
];
@ -554,66 +554,66 @@ class Group
}
$stmt = DBA::select('group', [], ['deleted' => false, 'uid' => DI::userSession()->getLocalUserId(), 'cid' => null], ['order' => ['name']]);
while ($group = DBA::fetch($stmt)) {
$selected = (($group_id == $group['id']) ? ' group-selected' : '');
while ($circle = DBA::fetch($stmt)) {
$selected = (($circle_id == $circle['id']) ? ' circle-selected' : '');
if ($editmode == 'full') {
$groupedit = [
'href' => 'group/' . $group['id'],
$circleedit = [
'href' => 'circle/' . $circle['id'],
'title' => DI::l10n()->t('edit'),
];
} else {
$groupedit = null;
$circleedit = null;
}
if ($each == 'group') {
$count = DBA::count('group_member', ['gid' => $group['id']]);
$group_name = sprintf('%s (%d)', $group['name'], $count);
if ($each == 'circle') {
$count = DBA::count('group_member', ['gid' => $circle['id']]);
$circle_name = sprintf('%s (%d)', $circle['name'], $count);
} else {
$group_name = $group['name'];
$circle_name = $circle['name'];
}
$display_groups[] = [
'id' => $group['id'],
$display_circles[] = [
'id' => $circle['id'],
'cid' => $cid,
'text' => $group_name,
'href' => $each . '/' . $group['id'],
'edit' => $groupedit,
'text' => $circle_name,
'href' => $each . '/' . $circle['id'],
'edit' => $circleedit,
'selected' => $selected,
'ismember' => in_array($group['id'], $member_of),
'ismember' => in_array($circle['id'], $member_of),
];
}
DBA::close($stmt);
// Don't show the groups on the network page when there is only one
if ((count($display_groups) <= 2) && ($each == 'network')) {
// Don't show the circles on the network page when there is only one
if ((count($display_circles) <= 2) && ($each == 'network')) {
return '';
}
$tpl = Renderer::getMarkupTemplate('group_side.tpl');
$tpl = Renderer::getMarkupTemplate('circle_side.tpl');
$o = Renderer::replaceMacros($tpl, [
'$add' => DI::l10n()->t('add'),
'$title' => DI::l10n()->t('Groups'),
'$groups' => $display_groups,
'newgroup' => $editmode == 'extended' || $editmode == 'full' ? 1 : '',
'grouppage' => 'group/',
'$edittext' => DI::l10n()->t('Edit group'),
'$ungrouped' => $every === 'contact' ? DI::l10n()->t('Contacts not in any group') : '',
'$ungrouped_selected' => (($group_id === 'none') ? 'group-selected' : ''),
'$createtext' => DI::l10n()->t('Create a new group'),
'$creategroup' => DI::l10n()->t('Group Name: '),
'$editgroupstext' => DI::l10n()->t('Edit groups'),
'$form_security_token' => BaseModule::getFormSecurityToken('group_edit'),
'$title' => DI::l10n()->t('Circles'),
'$circles' => $display_circles,
'$new_circle' => $editmode == 'extended' || $editmode == 'full' ? 1 : '',
'$circle_page' => 'circle/',
'$edittext' => DI::l10n()->t('Edit circle'),
'$uncircled' => $every === 'contact' ? DI::l10n()->t('Contacts not in any circle') : '',
'$uncircled_selected' => (($circle_id === 'none') ? 'circle-selected' : ''),
'$createtext' => DI::l10n()->t('Create a new circle'),
'$create_circle' => DI::l10n()->t('Circle Name: '),
'$edit_circles_text' => DI::l10n()->t('Edit circles'),
'$form_security_token' => BaseModule::getFormSecurityToken('circle_edit'),
]);
return $o;
}
/**
* Fetch the group id for the given contact id
* Fetch the circle id for the given contact id
*
* @param integer $id Contact ID
* @return integer Group IO
* @return integer Circle ID
*/
public static function getIdForForum(int $id): int
{
@ -623,8 +623,8 @@ class Group
return 0;
}
$group = DBA::selectFirst('group', ['id'], ['uid' => $contact['uid'], 'cid' => $id]);
if (empty($group)) {
$circle = DBA::selectFirst('group', ['id'], ['uid' => $contact['uid'], 'cid' => $id]);
if (empty($circle)) {
$fields = [
'uid' => $contact['uid'],
'name' => $contact['name'],
@ -633,14 +633,14 @@ class Group
DBA::insert('group', $fields);
$gid = DBA::lastInsertId();
} else {
$gid = $group['id'];
$gid = $circle['id'];
}
return $gid;
}
/**
* Fetch the followers of a given contact id and store them as group members
* Fetch the followers of a given contact id and store them as circle members
*
* @param integer $id Contact ID
* @return void
@ -664,9 +664,9 @@ class Group
return;
}
$group_members = DBA::selectToArray('group_member', ['contact-id'], ['gid' => $gid]);
if (!empty($group_members)) {
$current = array_unique(array_column($group_members, 'contact-id'));
$circle_members = DBA::selectToArray('group_member', ['contact-id'], ['gid' => $gid]);
if (!empty($circle_members)) {
$current = array_unique(array_column($circle_members, 'contact-id'));
} else {
$current = [];
}

View file

@ -3097,7 +3097,7 @@ class Contact
$contact_id = $contact['id'];
$result['cid'] = $contact_id;
Group::addMember(User::getDefaultGroup($uid), $contact_id);
Circle::addMember(User::getDefaultCircle($uid), $contact_id);
// Update the avatar
self::updateAvatar($contact_id, $ret['photo']);
@ -3238,7 +3238,7 @@ class Contact
DI::intro()->save($intro);
}
Group::addMember(User::getDefaultGroup($importer['uid']), $contact_record['id']);
Circle::addMember(User::getDefaultCircle($importer['uid']), $contact_record['id']);
if (($user['notify-flags'] & Notification\Type::INTRO) && $user['page-flags'] == User::PAGE_FLAGS_NORMAL) {
DI::notify()->createFromArray([

View file

@ -26,12 +26,12 @@ use Friendica\DI;
use Friendica\Model\Contact;
/**
* This class provides information about contact groups based on the "group_member" table.
* This class provides information about contact circles based on the "group_member" table.
*/
class Group
class Circle
{
/**
* Returns a list of contacts belonging in a group
* Returns a list of contacts belonging in a circle
*
* @param int $gid
* @return array
@ -42,10 +42,10 @@ class Group
$return = [];
if (intval($gid)) {
$stmt = DBA::p('SELECT `group_member`.`contact-id`, `contact`.*
$stmt = DBA::p('SELECT `circle_member`.`contact-id`, `contact`.*
FROM `contact`
INNER JOIN `group_member`
ON `contact`.`id` = `group_member`.`contact-id`
INNER JOIN `group_member` AS `circle_member`
ON `contact`.`id` = `circle_member`.`contact-id`
WHERE `gid` = ?
AND `contact`.`uid` = ?
AND NOT `contact`.`self`
@ -66,24 +66,24 @@ class Group
}
/**
* Returns ungrouped contact count or list for user
* Returns uncircled contact count or list for user
*
* Returns either the total number of ungrouped contacts for the given user
* id or a paginated list of ungrouped contacts.
* Returns either the total number of uncircled contacts for the given user
* id or a paginated list of uncircled contacts.
*
* @param int $uid uid
* @return array
* @throws \Exception
*/
public static function listUngrouped(int $uid)
public static function listUncircled(int $uid)
{
return Contact::selectToArray([], ["`uid` = ? AND NOT `self` AND NOT `deleted` AND NOT `blocked` AND NOT `pending` AND NOT `failed`
AND `id` NOT IN (SELECT DISTINCT(`contact-id`) FROM `group_member` INNER JOIN `group` ON `group`.`id` = `group_member`.`gid`
WHERE `group`.`uid` = ? AND `contact-id` = `contact`.`id`)", $uid, $uid]);
AND `id` NOT IN (SELECT DISTINCT(`contact-id`) FROM `group_member` AS `circle_member` INNER JOIN `group` AS `circle` ON `circle`.`id` = `circle_member`.`gid`
WHERE `circle`.`uid` = ? AND `contact-id` = `contact`.`id`)", $uid, $uid]);
}
/**
* Remove a contact from all groups
* Remove a contact from all circles
*
* @param integer $contact_id
*

View file

@ -2254,7 +2254,7 @@ class Item
if ($owner['page-flags'] == User::PAGE_FLAGS_PRVGROUP) {
$allow_cid = '';
$allow_gid = '<' . Group::FOLLOWERS . '>';
$allow_gid = '<' . Circle::FOLLOWERS . '>';
$deny_cid = '';
$deny_gid = '';
self::performActivity($item['id'], 'announce', $uid, $allow_cid, $allow_gid, $deny_cid, $deny_gid);
@ -2528,13 +2528,13 @@ class Item
$expand_followers = true;
}
$allow_people = $aclFormatter->expand($obj['allow_cid']);
$allow_groups = Group::expand($obj['uid'], $aclFormatter->expand($obj['allow_gid']), $check_dead, $expand_followers);
$deny_people = $aclFormatter->expand($obj['deny_cid']);
$deny_groups = Group::expand($obj['uid'], $aclFormatter->expand($obj['deny_gid']), $check_dead);
$recipients = array_unique(array_merge($allow_people, $allow_groups));
$deny = array_unique(array_merge($deny_people, $deny_groups));
$recipients = array_diff($recipients, $deny);
$allow_people = $aclFormatter->expand($obj['allow_cid']);
$allow_circles = Circle::expand($obj['uid'], $aclFormatter->expand($obj['allow_gid']), $check_dead, $expand_followers);
$deny_people = $aclFormatter->expand($obj['deny_cid']);
$deny_circles = Circle::expand($obj['uid'], $aclFormatter->expand($obj['deny_gid']), $check_dead);
$recipients = array_unique(array_merge($allow_people, $allow_circles));
$deny = array_unique(array_merge($deny_people, $deny_circles));
$recipients = array_diff($recipients, $deny);
return $recipients;
}
@ -2900,9 +2900,9 @@ class Item
/*
* Authenticated visitor. Unless pre-verified,
* check that the contact belongs to this $owner_id
* and load the groups the visitor belongs to.
* and load the circles the visitor belongs to.
* If pre-verified, the caller is expected to have already
* done this and passed the groups into this function.
* done this and passed the circles into this function.
*/
$permissionSets = DI::permissionSet()->selectByContactId($remote_user, $owner_id);

View file

@ -414,9 +414,9 @@ class Photo
* @param integer $scale Scale
* @param integer $type Photo type, optional, default: Photo::DEFAULT
* @param string $allow_cid Permissions, allowed contacts. optional, default = ""
* @param string $allow_gid Permissions, allowed groups. optional, default = ""
* @param string $deny_cid Permissions, denied contacts.optional, default = ""
* @param string $deny_gid Permissions, denied group.optional, default = ""
* @param string $allow_gid Permissions, allowed circles. optional, default = ""
* @param string $deny_cid Permissions, denied contacts. optional, default = ""
* @param string $deny_gid Permissions, denied circle. optional, default = ""
* @param string $desc Photo caption. optional, default = ""
*
* @return boolean True on success
@ -836,7 +836,7 @@ class Photo
* @return string
* @throws \Exception
*/
public static function setPermissionFromBody($body, $uid, $original_contact_id, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny)
public static function setPermissionFromBody($body, $uid, $original_contact_id, $str_contact_allow, $str_circle_allow, $str_contact_deny, $str_circle_deny)
{
// Simplify image codes
$img_body = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $body);
@ -881,7 +881,7 @@ class Photo
* Then set the permissions to public.
*/
self::setPermissionForResource($image_rid, $uid, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
self::setPermissionForResource($image_rid, $uid, $str_contact_allow, $str_circle_allow, $str_contact_deny, $str_circle_deny);
}
return true;
@ -894,15 +894,15 @@ class Photo
* @param string $image_rid
* @param integer $uid
* @param string $str_contact_allow
* @param string $str_group_allow
* @param string $str_circle_allow
* @param string $str_contact_deny
* @param string $str_group_deny
* @param string $str_circle_deny
* @return void
*/
public static function setPermissionForResource(string $image_rid, int $uid, string $str_contact_allow, string $str_group_allow, string $str_contact_deny, string $str_group_deny)
public static function setPermissionForResource(string $image_rid, int $uid, string $str_contact_allow, string $str_circle_allow, string $str_contact_deny, string $str_circle_deny)
{
$fields = ['allow_cid' => $str_contact_allow, 'allow_gid' => $str_group_allow,
'deny_cid' => $str_contact_deny, 'deny_gid' => $str_group_deny,
$fields = ['allow_cid' => $str_contact_allow, 'allow_gid' => $str_circle_allow,
'deny_cid' => $str_contact_deny, 'deny_gid' => $str_circle_deny,
'accessible' => DI::pConfig()->get($uid, 'system', 'accessible-photos', false)];
$condition = ['resource-id' => $image_rid, 'uid' => $uid];
@ -1228,9 +1228,9 @@ class Photo
* @param string $album Album name
* @param string $description Photo caption
* @param string $allow_cid Permissions, allowed contacts
* @param string $allow_gid Permissions, allowed groups
* @param string $allow_gid Permissions, allowed circles
* @param string $deny_cid Permissions, denied contacts
* @param string $deny_gid Permissions, denied group
* @param string $deny_gid Permissions, denied circles
*
* @return integer preview photo size
* @throws \Friendica\Network\HTTPException\InternalServerErrorException

View file

@ -483,23 +483,23 @@ class User
}
/**
* Returns the default group for a given user and network
* Returns the default circle for a given user and network
*
* @param int $uid User id
*
* @return int group id
* @return int circle id
* @throws Exception
*/
public static function getDefaultGroup(int $uid): int
public static function getDefaultCircle(int $uid): int
{
$user = DBA::selectFirst('user', ['def_gid'], ['uid' => $uid]);
if (DBA::isResult($user)) {
$default_group = $user["def_gid"];
$default_circle = $user['def_gid'];
} else {
$default_group = 0;
$default_circle = 0;
}
return $default_group;
return $default_circle;
}
/**
@ -1188,13 +1188,13 @@ class User
throw new Exception(DI::l10n()->t('An error occurred creating your self contact. Please try again.'));
}
// Create a group with no members. This allows somebody to use it
// right away as a default group for new contacts.
$def_gid = Group::create($uid, DI::l10n()->t('Friends'));
// Create a circle with no members. This allows somebody to use it
// right away as a default circle for new contacts.
$def_gid = Circle::create($uid, DI::l10n()->t('Friends'));
if (!$def_gid) {
DBA::delete('user', ['uid' => $uid]);
throw new Exception(DI::l10n()->t('An error occurred creating your default contact group. Please try again.'));
throw new Exception(DI::l10n()->t('An error occurred creating your default contact circle. Please try again.'));
}
$fields = ['def_gid' => $def_gid];

View file

@ -131,7 +131,7 @@ class Site extends BaseAdmin
$temppath = (!empty($_POST['temppath']) ? trim($_POST['temppath']) : '');
$singleuser = (!empty($_POST['singleuser']) ? trim($_POST['singleuser']) : '');
$only_tag_search = !empty($_POST['only_tag_search']);
$compute_group_counts = !empty($_POST['compute_group_counts']);
$compute_circle_counts = !empty($_POST['compute_circle_counts']);
$check_new_version_url = (!empty($_POST['check_new_version_url']) ? trim($_POST['check_new_version_url']) : 'none');
$worker_queues = (!empty($_POST['worker_queues']) ? intval($_POST['worker_queues']) : 10);
@ -278,7 +278,7 @@ class Site extends BaseAdmin
$transactionConfig->set('system', 'temppath', $temppath);
$transactionConfig->set('system', 'only_tag_search' , $only_tag_search);
$transactionConfig->set('system', 'compute_group_counts', $compute_group_counts);
$transactionConfig->set('system', 'compute_circle_counts', $compute_circle_counts);
$transactionConfig->set('system', 'worker_queues' , $worker_queues);
$transactionConfig->set('system', 'worker_fastlane' , $worker_fastlane);
@ -452,7 +452,7 @@ class Site extends BaseAdmin
'$block_public' => ['block_public', DI::l10n()->t('Block public'), DI::config()->get('system', 'block_public'), DI::l10n()->t('Check to block public access to all otherwise public personal pages on this site unless you are currently logged in.')],
'$force_publish' => ['publish_all', DI::l10n()->t('Force publish'), DI::config()->get('system', 'publish_all'), DI::l10n()->t('Check to force all profiles on this site to be listed in the site directory.') . '<strong>' . DI::l10n()->t('Enabling this may violate privacy laws like the GDPR') . '</strong>'],
'$global_directory' => ['directory', DI::l10n()->t('Global directory URL'), DI::config()->get('system', 'directory'), DI::l10n()->t('URL to the global directory. If this is not set, the global directory is completely unavailable to the application.')],
'$newuser_private' => ['newuser_private', DI::l10n()->t('Private posts by default for new users'), DI::config()->get('system', 'newuser_private'), DI::l10n()->t('Set default post permissions for all new members to the default privacy group rather than public.')],
'$newuser_private' => ['newuser_private', DI::l10n()->t('Private posts by default for new users'), DI::config()->get('system', 'newuser_private'), DI::l10n()->t('Set default post permissions for all new members to the default privacy circle rather than public.')],
'$enotify_no_content' => ['enotify_no_content', DI::l10n()->t('Don\'t include post content in email notifications'), DI::config()->get('system', 'enotify_no_content'), DI::l10n()->t('Don\'t include the content of a post/comment/private message/etc. in the email notifications that are sent out from this site, as a privacy measure.')],
'$private_addons' => ['private_addons', DI::l10n()->t('Disallow public access to addons listed in the apps menu.'), DI::config()->get('config', 'private_addons'), DI::l10n()->t('Checking this box will restrict addons listed in the apps menu to members only.')],
'$disable_embedded' => ['disable_embedded', DI::l10n()->t('Don\'t embed private images in posts'), DI::config()->get('system', 'disable_embedded'), DI::l10n()->t('Don\'t replace locally-hosted private photos in posts with an embedded copy of the image. This means that contacts who receive posts containing private photos will have to authenticate and load each image, which may take a while.')],
@ -504,7 +504,7 @@ class Site extends BaseAdmin
'$max_display_comments' => ['max_display_comments', DI::l10n()->t('Maximum numbers of comments per post on the display page'), DI::config()->get('system', 'max_display_comments'), DI::l10n()->t('How many comments should be shown on the single view for each post? Default value is 1000.')],
'$temppath' => ['temppath', DI::l10n()->t('Temp path'), DI::config()->get('system', 'temppath'), DI::l10n()->t('If you have a restricted system where the webserver can\'t access the system temp path, enter another path here.')],
'$only_tag_search' => ['only_tag_search', DI::l10n()->t('Only search in tags'), DI::config()->get('system', 'only_tag_search'), DI::l10n()->t('On large systems the text search can slow down the system extremely.')],
'$compute_group_counts' => ['compute_group_counts', DI::l10n()->t('Generate counts per contact group when calculating network count'), DI::config()->get('system', 'compute_group_counts'), DI::l10n()->t('On systems with users that heavily use contact groups the query can be very expensive.')],
'$compute_circle_counts' => ['compute_circle_counts', DI::l10n()->t('Generate counts per contact circle when calculating network count'), DI::config()->get('system', 'compute_group_counts') ?? DI::config()->get('system', 'compute_circle_counts'), DI::l10n()->t('On systems with users that heavily use contact circles the query can be very expensive.')],
'$worker_queues' => ['worker_queues', DI::l10n()->t('Maximum number of parallel workers'), DI::config()->get('system', 'worker_queues'), DI::l10n()->t('On shared hosters set this to %d. On larger systems, values of %d are great. Default value is %d.', 5, 20, 10)],
'$worker_fastlane' => ['worker_fastlane', DI::l10n()->t('Enable fastlane'), DI::config()->get('system', 'worker_fastlane'), DI::l10n()->t('When enabed, the fastlane mechanism starts an additional worker if processes with higher priority are blocked by processes of lower priority.')],

View file

@ -19,14 +19,15 @@
*
*/
namespace Friendica\Module\Api\Friendica\Group;
namespace Friendica\Module\Api\Friendica\Circle;
use Friendica\Database\DBA;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException;
/**
* API endpoint: /api/friendica/circle_create
* API endpoint: /api/friendica/group_create
*/
class Create extends BaseApi
@ -43,23 +44,22 @@ class Create extends BaseApi
// error if no name specified
if ($name == '') {
throw new HTTPException\BadRequestException('group name not specified');
throw new HTTPException\BadRequestException('circle name not specified');
}
// error message if specified group name already exists
// error message if specified circle name already exists
if (DBA::exists('group', ['uid' => $uid, 'name' => $name, 'deleted' => false])) {
throw new HTTPException\BadRequestException('group name already exists');
throw new HTTPException\BadRequestException('circle name already exists');
}
// Check if the group needs to be reactivated
// Check if the circle needs to be reactivated
if (DBA::exists('group', ['uid' => $uid, 'name' => $name, 'deleted' => true])) {
$reactivate_group = true;
$reactivate_circle = true;
}
// create group
$ret = Group::create($uid, $name);
$ret = Circle::create($uid, $name);
if ($ret) {
$gid = Group::getIdByName($uid, $name);
$gid = Circle::getIdByName($uid, $name);
} else {
throw new HTTPException\BadRequestException('other API error');
}
@ -70,7 +70,7 @@ class Create extends BaseApi
foreach ($users as $user) {
$cid = $user['cid'];
if (DBA::exists('contact', ['id' => $cid, 'uid' => $uid])) {
Group::addMember($gid, $cid);
Circle::addMember($gid, $cid);
} else {
$erroraddinguser = true;
$errorusers[] = $cid;
@ -78,7 +78,7 @@ class Create extends BaseApi
}
// return success message incl. missing users in array
$status = ($erroraddinguser ? 'missing user' : ((isset($reactivate_group) && $reactivate_group) ? 'reactivated' : 'ok'));
$status = ($erroraddinguser ? 'missing user' : (!empty($reactivate_circle) ? 'reactivated' : 'ok'));
$result = ['success' => true, 'gid' => $gid, 'name' => $name, 'status' => $status, 'wrong users' => $errorusers];

View file

@ -19,15 +19,16 @@
*
*/
namespace Friendica\Module\Api\Friendica\Group;
namespace Friendica\Module\Api\Friendica\Circle;
use Friendica\Database\DBA;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException\BadRequestException;
/**
* API endpoint: /api/friendica/group/delete
* API endpoint: /api/friendica/circle/delete
*/
class Delete extends BaseApi
{
@ -55,16 +56,16 @@ class Delete extends BaseApi
// error message if specified gid is not in database
if (!DBA::exists('group', ['uid' => $uid, 'id' => $request['gid'], 'name' => $request['name']])) {
throw new BadRequestException('wrong group name');
throw new BadRequestException('wrong circle name');
}
// delete group
$gid = Group::getIdByName($uid, $request['name']);
// delete circle
$gid = Circle::getIdByName($uid, $request['name']);
if (empty($request['gid'])) {
throw new BadRequestException('other API error');
}
$ret = Group::remove($gid);
$ret = Circle::remove($gid);
if ($ret) {
// return success

View file

@ -19,7 +19,7 @@
*
*/
namespace Friendica\Module\Api\Friendica\Group;
namespace Friendica\Module\Api\Friendica\Circle;
use Friendica\Database\DBA;
use Friendica\DI;
@ -28,6 +28,7 @@ use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException;
/**
* API endpoint: /api/friendica/circle_show
* API endpoint: /api/friendica/group_show
*/
class Show extends BaseApi
@ -41,22 +42,22 @@ class Show extends BaseApi
// params
$gid = $this->getRequestValue($request, 'gid', 0);
// get data of the specified group id or all groups if not specified
// get data of the specified circle id or all circles if not specified
if ($gid != 0) {
$groups = DBA::selectToArray('group', [], ['deleted' => false, 'uid' => $uid, 'id' => $gid]);
$circles = DBA::selectToArray('group', [], ['deleted' => false, 'uid' => $uid, 'id' => $gid]);
// error message if specified gid is not in database
if (!DBA::isResult($groups)) {
if (!DBA::isResult($circles)) {
throw new HTTPException\BadRequestException('gid not available');
}
} else {
$groups = DBA::selectToArray('group', [], ['deleted' => false, 'uid' => $uid]);
$circles = DBA::selectToArray('group', [], ['deleted' => false, 'uid' => $uid]);
}
// loop through all groups and retrieve all members for adding data in the user array
// loop through all circles and retrieve all members for adding data in the user array
$grps = [];
foreach ($groups as $rr) {
$members = Contact\Group::getById($rr['id']);
foreach ($circles as $circle) {
$members = Contact\Circle::getById($circle['id']);
$users = [];
if ($type == 'xml') {
@ -71,7 +72,7 @@ class Show extends BaseApi
$users[] = DI::twitterUser()->createFromContactId($member['contact-id'], $uid, true)->toArray();
}
}
$grps[] = ['name' => $rr['name'], 'gid' => $rr['id'], $user_element => $users];
$grps[] = ['name' => $circle['name'], 'gid' => $circle['id'], $user_element => $users];
}
$this->response->exit('group_update', ['group' => $grps], $this->parameters['extension'] ?? null);

View file

@ -19,15 +19,16 @@
*
*/
namespace Friendica\Module\Api\Friendica\Group;
namespace Friendica\Module\Api\Friendica\Circle;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Module\BaseApi;
use Friendica\Network\HTTPException\BadRequestException;
/**
* API endpoint: /api/friendica/circle_update
* API endpoint: /api/friendica/group_update
*/
class Update extends BaseApi
@ -45,7 +46,7 @@ class Update extends BaseApi
// error if no name specified
if (!$name) {
throw new BadRequestException('group name not specified');
throw new BadRequestException('circle name not specified');
}
// error if no gid specified
@ -54,15 +55,15 @@ class Update extends BaseApi
}
// remove members
$members = Contact\Group::getById($gid);
$members = Contact\Circle::getById($gid);
foreach ($members as $member) {
$cid = $member['id'];
foreach ($users as $user) {
$found = $user['cid'] == $cid;
}
if (!isset($found) || !$found) {
$gid = Group::getIdByName($uid, $name);
Group::removeMember($gid, $cid);
$gid = Circle::getIdByName($uid, $name);
Circle::removeMember($gid, $cid);
}
}
@ -73,7 +74,7 @@ class Update extends BaseApi
$cid = $user['cid'];
if (DBA::exists('contact', ['id' => $cid, 'uid' => $uid])) {
Group::addMember($gid, $cid);
Circle::addMember($gid, $cid);
} else {
$erroraddinguser = true;
$errorusers[] = $cid;

View file

@ -53,9 +53,9 @@ class Create extends BaseApi
'place' => '', //location of the event
'publish' => 0, //publish message
'allow_cid' => '', //array of allowed person, if access restricted
'allow_gid' => '', //array of allowed groups, if access restricted
'allow_gid' => '', //array of allowed circles, if access restricted
'deny_cid' => '', //array of denied person, if access restricted
'deny_gid' => '', //array of denied groups, if access restricted
'deny_gid' => '', //array of denied circles, if access restricted
], $request);
// error if no name specified

View file

@ -78,8 +78,8 @@ class Create extends BaseApi
$acl_input_error = false;
$acl_input_error |= !ACL::isValidContact($allow_cid, $uid);
$acl_input_error |= !ACL::isValidContact($deny_cid, $uid);
$acl_input_error |= !ACL::isValidGroup($allow_gid, $uid);
$acl_input_error |= !ACL::isValidGroup($deny_gid, $uid);
$acl_input_error |= !ACL::isValidCircle($allow_gid, $uid);
$acl_input_error |= !ACL::isValidCircle($deny_gid, $uid);
if ($acl_input_error) {
throw new HTTPException\BadRequestException('acl data invalid');
}

View file

@ -79,8 +79,8 @@ class Update extends BaseApi
$acl_input_error = false;
$acl_input_error |= !ACL::isValidContact($allow_cid, $uid);
$acl_input_error |= !ACL::isValidContact($deny_cid, $uid);
$acl_input_error |= !ACL::isValidGroup($allow_gid, $uid);
$acl_input_error |= !ACL::isValidGroup($deny_gid, $uid);
$acl_input_error |= !ACL::isValidCircle($allow_gid, $uid);
$acl_input_error |= !ACL::isValidCircle($deny_gid, $uid);
if ($acl_input_error) {
throw new HTTPException\BadRequestException('acl data invalid');
}

View file

@ -53,11 +53,11 @@ class Lists extends BaseApi
$cdata = Contact::getPublicAndUserContactID($id, $uid);
if (!empty($cdata['user'])) {
$groups = DBA::select('group_member', ['gid'], ['contact-id' => $cdata['user']]);
while ($group = DBA::fetch($groups)) {
$lists[] = DI::mstdnList()->createFromGroupId($group['gid']);
$circles = DBA::select('group_member', ['gid'], ['contact-id' => $cdata['user']]);
while ($circle = DBA::fetch($circles)) {
$lists[] = DI::mstdnList()->createFromCircleId($circle['gid']);
}
DBA::close($groups);
DBA::close($circles);
}
System::jsonExit($lists);

View file

@ -24,7 +24,7 @@ namespace Friendica\Module\Api\Mastodon;
use Friendica\Core\System;
use Friendica\DI;
use Friendica\Module\BaseApi;
use Friendica\Model\Group;
use Friendica\Model\Circle;
/**
* @see https://docs.joinmastodon.org/methods/timelines/lists/
@ -40,11 +40,11 @@ class Lists extends BaseApi
DI::mstdnError()->UnprocessableEntity();
}
if (!Group::exists($this->parameters['id'], $uid)) {
if (!Circle::exists($this->parameters['id'], $uid)) {
DI::mstdnError()->RecordNotFound();
}
if (!Group::remove($this->parameters['id'])) {
if (!Circle::remove($this->parameters['id'])) {
DI::mstdnError()->InternalError();
}
@ -64,14 +64,14 @@ class Lists extends BaseApi
DI::mstdnError()->UnprocessableEntity();
}
Group::create($uid, $request['title']);
Circle::create($uid, $request['title']);
$id = Group::getIdByName($uid, $request['title']);
$id = Circle::getIdByName($uid, $request['title']);
if (!$id) {
DI::mstdnError()->InternalError();
}
System::jsonExit(DI::mstdnList()->createFromGroupId($id));
System::jsonExit(DI::mstdnList()->createFromCircleId($id));
}
public function put(array $request = [])
@ -85,7 +85,7 @@ class Lists extends BaseApi
DI::mstdnError()->UnprocessableEntity();
}
Group::update($this->parameters['id'], $request['title']);
Circle::update($this->parameters['id'], $request['title']);
}
/**
@ -99,18 +99,16 @@ class Lists extends BaseApi
if (empty($this->parameters['id'])) {
$lists = [];
$groups = Group::getByUserId($uid);
foreach ($groups as $group) {
$lists[] = DI::mstdnList()->createFromGroupId($group['id']);
foreach (Circle::getByUserId($uid) as $circle) {
$lists[] = DI::mstdnList()->createFromCircleId($circle['id']);
}
} else {
$id = $this->parameters['id'];
if (!Group::exists($id, $uid)) {
if (!Circle::exists($id, $uid)) {
DI::mstdnError()->RecordNotFound();
}
$lists = DI::mstdnList()->createFromGroupId($id);
$lists = DI::mstdnList()->createFromCircleId($id);
}
System::jsonExit($lists);

View file

@ -24,7 +24,7 @@ namespace Friendica\Module\Api\Mastodon\Lists;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Module\BaseApi;
/**
@ -46,7 +46,7 @@ class Accounts extends BaseApi
DI::mstdnError()->UnprocessableEntity();
}
return Group::removeMembers($this->parameters['id'], $request['account_ids']);
return Circle::removeMembers($this->parameters['id'], $request['account_ids']);
}
protected function post(array $request = [])
@ -61,7 +61,7 @@ class Accounts extends BaseApi
DI::mstdnError()->UnprocessableEntity();
}
Group::addMembers($this->parameters['id'], $request['account_ids']);
Circle::addMembers($this->parameters['id'], $request['account_ids']);
}
/**

View file

@ -30,7 +30,7 @@ use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Model\Item;
use Friendica\Model\Photo;
use Friendica\Model\Post;
@ -230,7 +230,7 @@ class Statuses extends BaseApi
$item['deny_gid'] = $owner['deny_gid'];
} else {
$item['allow_cid'] = '';
$item['allow_gid'] = '<' . Group::FOLLOWERS . '>';
$item['allow_gid'] = '<' . Circle::FOLLOWERS . '>';
$item['deny_cid'] = '';
$item['deny_gid'] = '';
}
@ -241,7 +241,7 @@ class Statuses extends BaseApi
// The permissions are assigned in "expandTags"
break;
default:
if (is_numeric($request['visibility']) && Group::exists($request['visibility'], $uid)) {
if (is_numeric($request['visibility']) && Circle::exists($request['visibility'], $uid)) {
$item['allow_cid'] = '';
$item['allow_gid'] = '<' . $request['visibility'] . '>';
$item['deny_cid'] = '';

View file

@ -24,34 +24,34 @@ namespace Friendica\Module\Api\Twitter\Lists;
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Database\Database;
use Friendica\Factory\Api\Friendica\Group as FriendicaGroup;
use Friendica\Factory\Api\Friendica\Circle as FriendicaCircle;
use Friendica\Module\BaseApi;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Module\Api\ApiResponse;
use Friendica\Network\HTTPException;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
/**
* Update information about a group.
* Update information about a circle.
*
* @see https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-update
*/
class Create extends BaseApi
{
/** @var friendicaGroup */
private $friendicaGroup;
/** @var FriendicaCircle */
private $friendicaCircle;
/** @var Database */
private $dba;
public function __construct(Database $dba, FriendicaGroup $friendicaGroup, App $app, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, ApiResponse $response, array $server, array $parameters = [])
public function __construct(Database $dba, FriendicaCircle $friendicaCircle, App $app, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, ApiResponse $response, array $server, array $parameters = [])
{
parent::__construct($app, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->dba = $dba;
$this->friendicaGroup = $friendicaGroup;
$this->dba = $dba;
$this->friendicaCircle = $friendicaCircle;
}
protected function rawContent(array $request = [])
@ -63,22 +63,22 @@ class Create extends BaseApi
$name = $this->getRequestValue($request, 'name', '');
if ($name == '') {
throw new HTTPException\BadRequestException('group name not specified');
throw new HTTPException\BadRequestException('circle name not specified');
}
// error message if specified group name already exists
// error message if specified circle name already exists
if ($this->dba->exists('group', ['uid' => $uid, 'name' => $name, 'deleted' => false])) {
throw new HTTPException\BadRequestException('group name already exists');
throw new HTTPException\BadRequestException('circle name already exists');
}
$ret = Group::create($uid, $name);
$ret = Circle::create($uid, $name);
if ($ret) {
$gid = Group::getIdByName($uid, $name);
$gid = Circle::getIdByName($uid, $name);
} else {
throw new HTTPException\BadRequestException('other API error');
}
$grp = $this->friendicaGroup->createFromId($gid);
$grp = $this->friendicaCircle->createFromId($gid);
$this->response->exit('statuses', ['lists' => ['lists' => $grp]], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}

View file

@ -24,34 +24,34 @@ namespace Friendica\Module\Api\Twitter\Lists;
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Database\Database;
use Friendica\Factory\Api\Friendica\Group as FriendicaGroup;
use Friendica\Factory\Api\Friendica\Circle as FriendicaCirle;
use Friendica\Module\BaseApi;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Module\Api\ApiResponse;
use Friendica\Network\HTTPException;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
/**
* Delete a group.
* Delete a circle.
*
* @see https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-destroy
*/
class Destroy extends BaseApi
{
/** @var friendicaGroup */
private $friendicaGroup;
/** @var FriendicaCirle */
private $friendicaCircle;
/** @var Database */
private $dba;
public function __construct(Database $dba, FriendicaGroup $friendicaGroup, App $app, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, ApiResponse $response, array $server, array $parameters = [])
public function __construct(Database $dba, FriendicaCirle $friendicaCircle, App $app, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, ApiResponse $response, array $server, array $parameters = [])
{
parent::__construct($app, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->dba = $dba;
$this->friendicaGroup = $friendicaGroup;
$this->dba = $dba;
$this->friendicaCircle = $friendicaCircle;
}
protected function rawContent(array $request = [])
@ -67,16 +67,16 @@ class Destroy extends BaseApi
throw new HTTPException\BadRequestException('gid not specified');
}
// get data of the specified group id
$group = $this->dba->selectFirst('group', [], ['uid' => $uid, 'id' => $gid]);
// get data of the specified circle id
$circle = $this->dba->selectFirst('group', [], ['uid' => $uid, 'id' => $gid]);
// error message if specified gid is not in database
if (!$group) {
if (!$circle) {
throw new HTTPException\BadRequestException('gid not available');
}
$list = $this->friendicaGroup->createFromId($gid);
$list = $this->friendicaCircle->createFromId($gid);
if (Group::remove($gid)) {
if (Circle::remove($gid)) {
$this->response->exit('statuses', ['lists' => ['lists' => $list]], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}
}

View file

@ -24,7 +24,7 @@ namespace Friendica\Module\Api\Twitter\Lists;
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Database\Database;
use Friendica\Factory\Api\Friendica\Group as FriendicaGroup;
use Friendica\Factory\Api\Friendica\Circle as FriendicaCircle;
use Friendica\Module\BaseApi;
use Friendica\Model\Contact;
use Friendica\Module\Api\ApiResponse;
@ -32,36 +32,36 @@ use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
/**
* Returns all groups the user owns.
* Returns all circles the user owns.
*
* @see https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-ownerships
*/
class Ownership extends BaseApi
{
/** @var friendicaGroup */
private $friendicaGroup;
/** @var FriendicaCircle */
private $friendicaCircle;
/** @var Database */
private $dba;
public function __construct(Database $dba, FriendicaGroup $friendicaGroup, App $app, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, ApiResponse $response, array $server, array $parameters = [])
public function __construct(Database $dba, FriendicaCircle $friendicaCircle, App $app, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, ApiResponse $response, array $server, array $parameters = [])
{
parent::__construct($app, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->dba = $dba;
$this->friendicaGroup = $friendicaGroup;
$this->dba = $dba;
$this->friendicaCircle = $friendicaCircle;
}
protected function rawContent(array $request = [])
{
BaseApi::checkAllowedScope(BaseApi::SCOPE_READ);
$uid = BaseApi::getCurrentUserID();
$groups = $this->dba->select('group', [], ['deleted' => false, 'uid' => $uid, 'cid' => null]);
$circles = $this->dba->select('group', [], ['deleted' => false, 'uid' => $uid, 'cid' => null]);
// loop through all groups
// loop through all circles
$lists = [];
foreach ($groups as $group) {
$lists[] = $this->friendicaGroup->createFromId($group['id']);
foreach ($circles as $circle) {
$lists[] = $this->friendicaCircle->createFromId($circle['id']);
}
$this->response->exit('statuses', ['lists' => ['lists' => $lists]], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));

View file

@ -36,7 +36,7 @@ use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
/**
* Returns recent statuses from users in the specified group.
* Returns recent statuses from users in the specified circle.
*
* @see https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-ownerships
*/
@ -76,9 +76,9 @@ class Statuses extends BaseApi
$start = max(0, ($page - 1) * $count);
$groups = $this->dba->selectToArray('group_member', ['contact-id'], ['gid' => $request['list_id']]);
$gids = array_column($groups, 'contact-id');
$condition = ['uid' => $uid, 'gravity' => [Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT], 'contact-id' => $gids];
$members = $this->dba->selectToArray('group_member', ['contact-id'], ['gid' => $request['list_id']]);
$cids = array_column($members, 'contact-id');
$condition = ['uid' => $uid, 'gravity' => [Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT], 'contact-id' => $cids];
$condition = DBA::mergeConditions($condition, ["`uri-id` > ?", $since_id]);
if ($max_id > 0) {

View file

@ -24,34 +24,34 @@ namespace Friendica\Module\Api\Twitter\Lists;
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Database\Database;
use Friendica\Factory\Api\Friendica\Group as FriendicaGroup;
use Friendica\Factory\Api\Friendica\Circle as FriendicaCircle;
use Friendica\Module\BaseApi;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Module\Api\ApiResponse;
use Friendica\Network\HTTPException;
use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
/**
* Update information about a group.
* Update information about a circle.
*
* @see https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-update
*/
class Update extends BaseApi
{
/** @var friendicaGroup */
private $friendicaGroup;
/** @var FriendicaCircle */
private $friendicaCircle;
/** @var Database */
private $dba;
public function __construct(Database $dba, FriendicaGroup $friendicaGroup, App $app, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, ApiResponse $response, array $server, array $parameters = [])
public function __construct(Database $dba, FriendicaCircle $friendicaCircle, App $app, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, ApiResponse $response, array $server, array $parameters = [])
{
parent::__construct($app, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->dba = $dba;
$this->friendicaGroup = $friendicaGroup;
$this->dba = $dba;
$this->friendicaCircle = $friendicaCircle;
}
protected function rawContent(array $request = [])
@ -68,15 +68,15 @@ class Update extends BaseApi
throw new HTTPException\BadRequestException('gid not specified');
}
// get data of the specified group id
$group = $this->dba->selectFirst('group', [], ['uid' => $uid, 'id' => $gid]);
// get data of the specified circle id
$circle = $this->dba->selectFirst('group', [], ['uid' => $uid, 'id' => $gid]);
// error message if specified gid is not in database
if (!$group) {
if (!$circle) {
throw new HTTPException\BadRequestException('gid not available');
}
if (Group::update($gid, $name)) {
$list = $this->friendicaGroup->createFromId($gid);
if (Circle::update($gid, $name)) {
$list = $this->friendicaCircle->createFromId($gid);
$this->response->exit('statuses', ['lists' => ['lists' => $list]], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}

View file

@ -62,9 +62,9 @@ class Update extends BaseApi
'source' => '',
'include_entities' => false,
'contact_allow' => $owner['allow_cid'],
'group_allow' => $owner['allow_gid'],
'circle_allow' => $owner['allow_gid'],
'contact_deny' => $owner['deny_cid'],
'group_deny' => $owner['deny_gid'],
'circle_deny' => $owner['deny_gid'],
], $request);
if (!empty($request['htmlstatus'])) {
@ -102,9 +102,9 @@ class Update extends BaseApi
$aclFormatter = DI::aclFormatter();
$item['allow_cid'] = $aclFormatter->toString($request['contact_allow']);
$item['allow_gid'] = $aclFormatter->toString($request['group_allow']);
$item['allow_gid'] = $aclFormatter->toString($request['circle_allow']);
$item['deny_cid'] = $aclFormatter->toString($request['contact_deny']);
$item['deny_gid'] = $aclFormatter->toString($request['group_deny']);
$item['deny_gid'] = $aclFormatter->toString($request['circle_deny']);
if (!empty($item['allow_cid'] . $item['allow_gid'] . $item['deny_cid'] . $item['deny_gid'])) {
$item['private'] = Item::PRIVATE;

View file

@ -212,14 +212,14 @@ class API extends BaseModule
}
$strAclContactAllow = isset($request['contact_allow']) ? $aclFormatter->toString($request['contact_allow']) : $user['allow_cid'] ?? '';
$strAclGroupAllow = isset($request['group_allow']) ? $aclFormatter->toString($request['group_allow']) : $user['allow_gid'] ?? '';
$strContactDeny = isset($request['contact_deny']) ? $aclFormatter->toString($request['contact_deny']) : $user['deny_cid'] ?? '';
$strGroupDeny = isset($request['group_deny']) ? $aclFormatter->toString($request['group_deny']) : $user['deny_gid'] ?? '';
$strAclCircleAllow = isset($request['circle_allow']) ? $aclFormatter->toString($request['circle_allow']) : $user['allow_gid'] ?? '';
$strContactDeny = isset($request['contact_deny']) ? $aclFormatter->toString($request['contact_deny']) : $user['deny_cid'] ?? '';
$strCircleDeny = isset($request['circle_deny']) ? $aclFormatter->toString($request['circle_deny']) : $user['deny_gid'] ?? '';
$visibility = $request['visibility'] ?? '';
if ($visibility === 'public') {
// The ACL selector introduced in version 2019.12 sends ACL input data even when the Public visibility is selected
$strAclContactAllow = $strAclGroupAllow = $strContactDeny = $strGroupDeny = '';
$strAclContactAllow = $strAclCircleAllow = $strContactDeny = $strCircleDeny = '';
} elseif ($visibility === 'custom') {
// Since we know from the visibility parameter the item should be private, we have to prevent the empty ACL
// case that would make it public. So we always append the author's contact id to the allowed contacts.
@ -228,9 +228,9 @@ class API extends BaseModule
}
} else {
$strAclContactAllow = $aclFormatter->toString($self);
$strAclGroupAllow = '';
$strAclCircleAllow = '';
$strContactDeny = '';
$strGroupDeny = '';
$strCircleDeny = '';
}
$datarray = [
@ -244,9 +244,9 @@ class API extends BaseModule
'uid' => $uid,
'cid' => $cid,
'allow_cid' => $strAclContactAllow,
'allow_gid' => $strAclGroupAllow,
'allow_gid' => $strAclCircleAllow,
'deny_cid' => $strContactDeny,
'deny_gid' => $strGroupDeny,
'deny_gid' => $strCircleDeny,
'id' => $eventId,
];

View file

@ -28,7 +28,7 @@ use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model;
class Group extends BaseModule
class Circle extends BaseModule
{
protected function post(array $request = [])
{
@ -43,34 +43,34 @@ class Group extends BaseModule
// @TODO: Replace with parameter from router
if ((DI::args()->getArgc() == 2) && (DI::args()->getArgv()[1] === 'new')) {
BaseModule::checkFormSecurityTokenRedirectOnError('/group/new', 'group_edit');
BaseModule::checkFormSecurityTokenRedirectOnError('/circle/new', 'circle_edit');
$name = trim($request['groupname']);
$r = Model\Group::create(DI::userSession()->getLocalUserId(), $name);
$name = trim($request['circle_name']);
$r = Model\Circle::create(DI::userSession()->getLocalUserId(), $name);
if ($r) {
$r = Model\Group::getIdByName(DI::userSession()->getLocalUserId(), $name);
$r = Model\Circle::getIdByName(DI::userSession()->getLocalUserId(), $name);
if ($r) {
DI::baseUrl()->redirect('group/' . $r);
DI::baseUrl()->redirect('circle/' . $r);
}
} else {
DI::sysmsg()->addNotice(DI::l10n()->t('Could not create group.'));
DI::sysmsg()->addNotice(DI::l10n()->t('Could not create circle.'));
}
DI::baseUrl()->redirect('group');
DI::baseUrl()->redirect('circle');
}
// @TODO: Replace with parameter from router
if ((DI::args()->getArgc() == 2) && intval(DI::args()->getArgv()[1])) {
BaseModule::checkFormSecurityTokenRedirectOnError('/group', 'group_edit');
BaseModule::checkFormSecurityTokenRedirectOnError('/circle', 'circle_edit');
$group = DBA::selectFirst('group', ['id', 'name'], ['id' => DI::args()->getArgv()[1], 'uid' => DI::userSession()->getLocalUserId()]);
if (!DBA::isResult($group)) {
DI::sysmsg()->addNotice(DI::l10n()->t('Group not found.'));
$circle = DBA::selectFirst('group', ['id', 'name'], ['id' => DI::args()->getArgv()[1], 'uid' => DI::userSession()->getLocalUserId()]);
if (!DBA::isResult($circle)) {
DI::sysmsg()->addNotice(DI::l10n()->t('Circle not found.'));
DI::baseUrl()->redirect('contact');
}
$groupname = trim($_POST['groupname']);
if (strlen($groupname) && ($groupname != $group['name'])) {
if (!Model\Group::update($group['id'], $groupname)) {
DI::sysmsg()->addNotice(DI::l10n()->t('Group name was not changed.'));
$circlename = trim($_POST['circle_name']);
if (strlen($circlename) && ($circlename != $circle['name'])) {
if (!Model\Circle::update($circle['id'], $circlename)) {
DI::sysmsg()->addNotice(DI::l10n()->t('Circle name was not changed.'));
}
}
}
@ -84,11 +84,11 @@ class Group extends BaseModule
}
if (isset($this->parameters['command'])) {
$group_id = $this->parameters['group'];
$circle_id = $this->parameters['circle'];
$contact_id = $this->parameters['contact'];
if (!Model\Group::exists($group_id, DI::userSession()->getLocalUserId())) {
throw new \Exception(DI::l10n()->t('Unknown group.'), 404);
if (!Model\Circle::exists($circle_id, DI::userSession()->getLocalUserId())) {
throw new \Exception(DI::l10n()->t('Unknown circle.'), 404);
}
// @TODO Backward compatibility with user contacts, remove by version 2022.03
@ -112,18 +112,18 @@ class Group extends BaseModule
switch($this->parameters['command']) {
case 'add':
if (!Model\Group::addMember($group_id, $cdata['user'])) {
throw new \Exception(DI::l10n()->t('Unable to add the contact to the group.'), 500);
if (!Model\Circle::addMember($circle_id, $cdata['user'])) {
throw new \Exception(DI::l10n()->t('Unable to add the contact to the circle.'), 500);
}
$message = DI::l10n()->t('Contact successfully added to group.');
$message = DI::l10n()->t('Contact successfully added to circle.');
break;
case 'remove':
if (!Model\Group::removeMember($group_id, $cdata['user'])) {
throw new \Exception(DI::l10n()->t('Unable to remove the contact from the group.'), 500);
if (!Model\Circle::removeMember($circle_id, $cdata['user'])) {
throw new \Exception(DI::l10n()->t('Unable to remove the contact from the circle.'), 500);
}
$message = DI::l10n()->t('Contact successfully removed from group.');
$message = DI::l10n()->t('Contact successfully removed from circle.');
break;
}
} else {
@ -148,56 +148,58 @@ class Group extends BaseModule
$a = DI::app();
DI::page()['aside'] = Model\Group::sidebarWidget('contact', 'group', 'extended', ((DI::args()->getArgc() > 1) ? DI::args()->getArgv()[1] : 'everyone'));
DI::page()['aside'] = Model\Circle::sidebarWidget('contact', 'circle', 'extended', ((DI::args()->getArgc() > 1) ? DI::args()->getArgv()[1] : 'everyone'));
// With no group number provided we jump to the unassigned contacts as a starting point
// With no circle number provided we jump to the unassigned contacts as a starting point
// @TODO: Replace with parameter from router
if (DI::args()->getArgc() == 1) {
DI::baseUrl()->redirect('group/none');
DI::baseUrl()->redirect('circle/none');
}
// Switch to text mode interface if we have more than 'n' contacts or group members
$switchtotext = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'system', 'groupedit_image_limit');
// Switch to text mode interface if we have more than 'n' contacts or circle members
$switchtotext = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'system', 'circle_edit_image_limit') ??
DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'system', 'groupedit_image_limit');
if (is_null($switchtotext)) {
$switchtotext = DI::config()->get('system', 'groupedit_image_limit', 200);
$switchtotext = DI::config()->get('system', 'groupedit_image_limit') ??
DI::config()->get('system', 'circle_edit_image_limit');
}
$tpl = Renderer::getMarkupTemplate('group_edit.tpl');
$tpl = Renderer::getMarkupTemplate('circle_edit.tpl');
$context = [
'$submit' => DI::l10n()->t('Save Group'),
'$submit' => DI::l10n()->t('Save Circle'),
'$submit_filter' => DI::l10n()->t('Filter'),
];
// @TODO: Replace with parameter from router
if ((DI::args()->getArgc() == 2) && (DI::args()->getArgv()[1] === 'new')) {
return Renderer::replaceMacros($tpl, $context + [
'$title' => DI::l10n()->t('Create a group of contacts/friends.'),
'$gname' => ['groupname', DI::l10n()->t('Group Name: '), '', ''],
'$title' => DI::l10n()->t('Create a circle of contacts/friends.'),
'$gname' => ['circle_name', DI::l10n()->t('Circle Name: '), '', ''],
'$gid' => 'new',
'$form_security_token' => BaseModule::getFormSecurityToken("group_edit"),
'$form_security_token' => BaseModule::getFormSecurityToken('circle_edit'),
]);
}
$nogroup = false;
$nocircle = false;
// @TODO: Replace with parameter from router
if ((DI::args()->getArgc() == 2) && (DI::args()->getArgv()[1] === 'none') ||
(DI::args()->getArgc() == 1) && (DI::args()->getArgv()[0] === 'nogroup')) {
(DI::args()->getArgc() == 1) && (DI::args()->getArgv()[0] === 'nocircle')) {
$id = -1;
$nogroup = true;
$group = [
$nocircle = true;
$circle = [
'id' => $id,
'name' => DI::l10n()->t('Contacts not in any group'),
'name' => DI::l10n()->t('Contacts not in any circle'),
];
$members = [];
$preselected = [];
$context = $context + [
'$title' => $group['name'],
'$gname' => ['groupname', DI::l10n()->t('Group Name: '), $group['name'], ''],
'$title' => $circle['name'],
'$gname' => ['circle_name', DI::l10n()->t('Circle Name: '), $circle['name'], ''],
'$gid' => $id,
'$editable' => 0,
];
@ -205,25 +207,25 @@ class Group extends BaseModule
// @TODO: Replace with parameter from router
if ((DI::args()->getArgc() == 3) && (DI::args()->getArgv()[1] === 'drop')) {
BaseModule::checkFormSecurityTokenRedirectOnError('/group', 'group_drop', 't');
BaseModule::checkFormSecurityTokenRedirectOnError('/circle', 'circle_drop', 't');
// @TODO: Replace with parameter from router
if (intval(DI::args()->getArgv()[2])) {
if (!Model\Group::exists(DI::args()->getArgv()[2], DI::userSession()->getLocalUserId())) {
DI::sysmsg()->addNotice(DI::l10n()->t('Group not found.'));
if (!Model\Circle::exists(DI::args()->getArgv()[2], DI::userSession()->getLocalUserId())) {
DI::sysmsg()->addNotice(DI::l10n()->t('Circle not found.'));
DI::baseUrl()->redirect('contact');
}
if (!Model\Group::remove(DI::args()->getArgv()[2])) {
DI::sysmsg()->addNotice(DI::l10n()->t('Unable to remove group.'));
if (!Model\Circle::remove(DI::args()->getArgv()[2])) {
DI::sysmsg()->addNotice(DI::l10n()->t('Unable to remove circle.'));
}
}
DI::baseUrl()->redirect('group');
DI::baseUrl()->redirect('circle');
}
// @TODO: Replace with parameter from router
if ((DI::args()->getArgc() > 2) && intval(DI::args()->getArgv()[1]) && intval(DI::args()->getArgv()[2])) {
BaseModule::checkFormSecurityTokenForbiddenOnError('group_member_change', 't');
BaseModule::checkFormSecurityTokenForbiddenOnError('circle_member_change', 't');
if (DBA::exists('contact', ['id' => DI::args()->getArgv()[2], 'uid' => DI::userSession()->getLocalUserId(), 'self' => false, 'pending' => false, 'blocked' => false])) {
$change = intval(DI::args()->getArgv()[2]);
@ -232,13 +234,13 @@ class Group extends BaseModule
// @TODO: Replace with parameter from router
if ((DI::args()->getArgc() > 1) && intval(DI::args()->getArgv()[1])) {
$group = DBA::selectFirst('group', ['id', 'name'], ['id' => DI::args()->getArgv()[1], 'uid' => DI::userSession()->getLocalUserId(), 'deleted' => false]);
if (!DBA::isResult($group)) {
DI::sysmsg()->addNotice(DI::l10n()->t('Group not found.'));
$circle = DBA::selectFirst('group', ['id', 'name'], ['id' => DI::args()->getArgv()[1], 'uid' => DI::userSession()->getLocalUserId(), 'deleted' => false]);
if (!DBA::isResult($circle)) {
DI::sysmsg()->addNotice(DI::l10n()->t('Circle not found.'));
DI::baseUrl()->redirect('contact');
}
$members = Model\Contact\Group::getById($group['id']);
$members = Model\Contact\Circle::getById($circle['id']);
$preselected = [];
if (count($members)) {
@ -249,12 +251,12 @@ class Group extends BaseModule
if ($change) {
if (in_array($change, $preselected)) {
Model\Group::removeMember($group['id'], $change);
Model\Circle::removeMember($circle['id'], $change);
} else {
Model\Group::addMember($group['id'], $change);
Model\Circle::addMember($circle['id'], $change);
}
$members = Model\Contact\Group::getById($group['id']);
$members = Model\Contact\Circle::getById($circle['id']);
$preselected = [];
if (count($members)) {
foreach ($members as $member) {
@ -263,59 +265,59 @@ class Group extends BaseModule
}
}
$drop_tpl = Renderer::getMarkupTemplate('group_drop.tpl');
$drop_tpl = Renderer::getMarkupTemplate('circle_drop.tpl');
$drop_txt = Renderer::replaceMacros($drop_tpl, [
'$id' => $group['id'],
'$delete' => DI::l10n()->t('Delete Group'),
'$form_security_token' => BaseModule::getFormSecurityToken("group_drop"),
'$id' => $circle['id'],
'$delete' => DI::l10n()->t('Delete Circle'),
'$form_security_token' => BaseModule::getFormSecurityToken('circle_drop'),
]);
$context = $context + [
'$title' => $group['name'],
'$gname' => ['groupname', DI::l10n()->t('Group Name: '), $group['name'], ''],
'$gid' => $group['id'],
'$title' => $circle['name'],
'$gname' => ['circle_name', DI::l10n()->t('Circle Name: '), $circle['name'], ''],
'$gid' => $circle['id'],
'$drop' => $drop_txt,
'$form_security_token' => BaseModule::getFormSecurityToken('group_edit'),
'$edit_name' => DI::l10n()->t('Edit Group Name'),
'$form_security_token' => BaseModule::getFormSecurityToken('circle_edit'),
'$edit_name' => DI::l10n()->t('Edit Circle Name'),
'$editable' => 1,
];
}
if (!isset($group)) {
if (!isset($circle)) {
throw new \Friendica\Network\HTTPException\BadRequestException();
}
$groupeditor = [
$circle_editor = [
'label_members' => DI::l10n()->t('Members'),
'members' => [],
'label_contacts' => DI::l10n()->t('All Contacts'),
'group_is_empty' => DI::l10n()->t('Group is empty'),
'circle_is_empty' => DI::l10n()->t('Circle is empty'),
'contacts' => [],
];
$sec_token = addslashes(BaseModule::getFormSecurityToken('group_member_change'));
$sec_token = addslashes(BaseModule::getFormSecurityToken('circle_member_change'));
// Format the data of the group members
// Format the data of the circle members
foreach ($members as $member) {
if ($member['url']) {
$entry = Contact::getContactTemplateVars($member);
$entry['label'] = 'members';
$entry['photo_menu'] = '';
$entry['change_member'] = [
'title' => DI::l10n()->t("Remove contact from group"),
'gid' => $group['id'],
'title' => DI::l10n()->t('Remove contact from circle'),
'gid' => $circle['id'],
'cid' => $member['id'],
'sec_token' => $sec_token
];
$groupeditor['members'][] = $entry;
$circle_editor['members'][] = $entry;
} else {
Model\Group::removeMember($group['id'], $member['id']);
Model\Circle::removeMember($circle['id'], $member['id']);
}
}
if ($nogroup) {
$contacts = Model\Contact\Group::listUngrouped(DI::userSession()->getLocalUserId());
if ($nocircle) {
$contacts = Model\Contact\Circle::listUncircled(DI::userSession()->getLocalUserId());
} else {
$contacts_stmt = DBA::select('contact', [],
['rel' => [Model\Contact::FOLLOWER, Model\Contact::FRIEND, Model\Contact::SHARING],
@ -327,36 +329,36 @@ class Group extends BaseModule
}
if (DBA::isResult($contacts)) {
// Format the data of the contacts who aren't in the contact group
// Format the data of the contacts who aren't in the contact circle
foreach ($contacts as $member) {
if (!in_array($member['id'], $preselected)) {
$entry = Contact::getContactTemplateVars($member);
$entry['label'] = 'contacts';
if (!$nogroup)
if (!$nocircle)
$entry['photo_menu'] = [];
if (!$nogroup) {
if (!$nocircle) {
$entry['change_member'] = [
'title' => DI::l10n()->t("Add contact to group"),
'gid' => $group['id'],
'title' => DI::l10n()->t('Add contact to circle'),
'gid' => $circle['id'],
'cid' => $member['id'],
'sec_token' => $sec_token
];
}
$groupeditor['contacts'][] = $entry;
$circle_editor['contacts'][] = $entry;
}
}
}
$context['$groupeditor'] = $groupeditor;
$context['$circle_editor'] = $circle_editor;
// If there are to many contacts we could provide an alternative view mode
$total = count($groupeditor['members']) + count($groupeditor['contacts']);
$total = count($circle_editor['members']) + count($circle_editor['contacts']);
$context['$shortmode'] = (($switchtotext && ($total > $switchtotext)) ? true : false);
if ($change) {
$tpl = Renderer::getMarkupTemplate('groupeditor.tpl');
$tpl = Renderer::getMarkupTemplate('circle_editor.tpl');
echo Renderer::replaceMacros($tpl, $context);
System::exit();
}

View file

@ -191,7 +191,7 @@ class Contact extends BaseModule
$search = trim($_GET['search'] ?? '');
$nets = trim($_GET['nets'] ?? '');
$rel = trim($_GET['rel'] ?? '');
$group = trim($_GET['group'] ?? '');
$circle = trim($_GET['circle'] ?? '');
$accounttype = $_GET['accounttype'] ?? '';
$accounttypeid = User::getAccountTypeByString($accounttype);
@ -211,12 +211,12 @@ class Contact extends BaseModule
$follow_widget = Widget::follow();
}
$account_widget = Widget::accountTypes($_SERVER['REQUEST_URI'], $accounttype);
$account_widget = Widget::accountTypes($_SERVER['REQUEST_URI'], $accounttype);
$networks_widget = Widget::networks($_SERVER['REQUEST_URI'], $nets);
$rel_widget = Widget::contactRels($_SERVER['REQUEST_URI'], $rel);
$groups_widget = Widget::groups($_SERVER['REQUEST_URI'], $group);
$rel_widget = Widget::contactRels($_SERVER['REQUEST_URI'], $rel);
$circles_widget = Widget::circles($_SERVER['REQUEST_URI'], $circle);
DI::page()['aside'] .= $vcard_widget . $findpeople_widget . $follow_widget . $rel_widget . $groups_widget . $networks_widget . $account_widget;
DI::page()['aside'] .= $vcard_widget . $findpeople_widget . $follow_widget . $rel_widget . $circles_widget . $networks_widget . $account_widget;
$tpl = Renderer::getMarkupTemplate('contacts-head.tpl');
DI::page()['htmlhead'] .= Renderer::replaceMacros($tpl, [
@ -306,9 +306,9 @@ class Contact extends BaseModule
break;
}
if ($group) {
if ($circle) {
$sql_extra .= " AND `id` IN (SELECT `contact-id` FROM `group_member` WHERE `gid` = ?)";
$sql_values[] = $group;
$sql_values[] = $circle;
}
$networks = Widget::unavailableNetworks();
@ -391,11 +391,11 @@ class Contact extends BaseModule
'accesskey' => 'h',
],
[
'label' => DI::l10n()->t('Groups'),
'url' => 'group',
'label' => DI::l10n()->t('Circles'),
'url' => 'circle',
'sel' => '',
'title' => DI::l10n()->t('Organize your contact groups'),
'id' => 'contactgroups-tab',
'title' => DI::l10n()->t('Organize your contact circles'),
'id' => 'contactcircles-tab',
'accesskey' => 'e',
],
];

View file

@ -37,7 +37,7 @@ use Friendica\Core\Renderer;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Module;
use Friendica\Module\Response;
use Friendica\Network\HTTPException;
@ -222,13 +222,13 @@ class Profile extends BaseModule
}
$vcard_widget = Widget\VCard::getHTML($contact);
$groups_widget = '';
$circles_widget = '';
if (!in_array($localRelationship->rel, [Contact::NOTHING, Contact::SELF])) {
$groups_widget = Group::sidebarWidget('contact', 'group', 'full', 'everyone', $data['user']);
$circles_widget = Circle::sidebarWidget('contact', 'circle', 'full', 'everyone', $data['user']);
}
$this->page['aside'] .= $vcard_widget . $groups_widget;
$this->page['aside'] .= $vcard_widget . $circles_widget;
$o = '';
Nav::setSelected('contact');

View file

@ -36,7 +36,7 @@ use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Model\Item;
use Friendica\Model\Post;
use Friendica\Model\Profile;
@ -50,7 +50,7 @@ use Friendica\Util\DateTimeFormat;
class Network extends BaseModule
{
/** @var int */
private static $groupId;
private static $circleId;
/** @var int */
private static $forumContactId;
/** @var string */
@ -89,7 +89,7 @@ class Network extends BaseModule
$module = 'network';
DI::page()['aside'] .= Widget::accountTypes($module, self::$accountTypeString);
DI::page()['aside'] .= Group::sidebarWidget($module, $module . '/group', 'standard', self::$groupId);
DI::page()['aside'] .= Circle::sidebarWidget($module, $module . '/circle', 'standard', self::$circleId);
DI::page()['aside'] .= ForumManager::widget($module . '/forum', DI::userSession()->getLocalUserId(), self::$forumContactId);
DI::page()['aside'] .= Widget::postedByYear($module . '/archive', DI::userSession()->getLocalUserId(), false);
DI::page()['aside'] .= Widget::networks($module, !self::$forumContactId ? self::$network : '');
@ -131,8 +131,8 @@ class Network extends BaseModule
$a = DI::app();
$default_permissions = [];
if (self::$groupId) {
$default_permissions['allow_gid'] = [self::$groupId];
if (self::$circleId) {
$default_permissions['allow_gid'] = [self::$circleId];
}
$allowedCids = [];
@ -160,23 +160,23 @@ class Network extends BaseModule
}
$x = [
'lockstate' => self::$groupId || self::$forumContactId || self::$network || ACL::getLockstateForUserId($a->getLoggedInUserId()) ? 'lock' : 'unlock',
'lockstate' => self::$circleId || self::$forumContactId || self::$network || ACL::getLockstateForUserId($a->getLoggedInUserId()) ? 'lock' : 'unlock',
'acl' => ACL::getFullSelectorHTML(DI::page(), $a->getLoggedInUserId(), true, $default_permissions),
'bang' => ((self::$groupId || self::$forumContactId || self::$network) ? '!' : ''),
'bang' => ((self::$circleId || self::$forumContactId || self::$network) ? '!' : ''),
'content' => $content,
];
$o .= DI::conversation()->statusEditor($x);
}
if (self::$groupId) {
$group = DBA::selectFirst('group', ['name'], ['id' => self::$groupId, 'uid' => DI::userSession()->getLocalUserId()]);
if (!DBA::isResult($group)) {
DI::sysmsg()->addNotice(DI::l10n()->t('No such group'));
if (self::$circleId) {
$circle = DBA::selectFirst('group', ['name'], ['id' => self::$circleId, 'uid' => DI::userSession()->getLocalUserId()]);
if (!DBA::isResult($circle)) {
DI::sysmsg()->addNotice(DI::l10n()->t('No such circle'));
}
$o = Renderer::replaceMacros(Renderer::getMarkupTemplate('section_title.tpl'), [
'$title' => DI::l10n()->t('Group: %s', $group['name'])
'$title' => DI::l10n()->t('Circle: %s', $circle['name'])
]) . $o;
} elseif (self::$forumContactId) {
$contact = Contact::getById(self::$forumContactId);
@ -305,7 +305,7 @@ class Network extends BaseModule
protected function parseRequest(array $get)
{
self::$groupId = $this->parameters['group_id'] ?? 0;
self::$circleId = $this->parameters['circle_id'] ?? 0;
self::$forumContactId = $this->parameters['contact_id'] ?? 0;
@ -411,8 +411,8 @@ class Network extends BaseModule
$conditionStrings = DBA::mergeConditions($conditionStrings, ["`received` >= ? ", DateTimeFormat::convert(self::$dateTo, 'UTC', DI::app()->getTimeZone())]);
}
if (self::$groupId) {
$conditionStrings = DBA::mergeConditions($conditionStrings, ["`contact-id` IN (SELECT `contact-id` FROM `group_member` WHERE `gid` = ?)", self::$groupId]);
if (self::$circleId) {
$conditionStrings = DBA::mergeConditions($conditionStrings, ["`contact-id` IN (SELECT `contact-id` FROM `group_member` WHERE `gid` = ?)", self::$circleId]);
} elseif (self::$forumContactId) {
$conditionStrings = DBA::mergeConditions($conditionStrings,
["((`contact-id` = ?) OR `uri-id` IN (SELECT `parent-uri-id` FROM `post-user-view` WHERE (`contact-id` = ? AND `gravity` = ? AND `vid` = ? AND `uid` = ?)))",
@ -476,10 +476,10 @@ class Network extends BaseModule
$parents = [];
}
// We aren't going to try and figure out at the item, group, and page
// We aren't going to try and figure out at the item, circle, and page
// level which items you've seen and which you haven't. If you're looking
// at the top level network page just mark everything seen.
if (!self::$groupId && !self::$forumContactId && !self::$star && !self::$mention) {
if (!self::$circleId && !self::$forumContactId && !self::$star && !self::$mention) {
$condition = ['unseen' => true, 'uid' => DI::userSession()->getLocalUserId()];
self::setItemsSeenByCondition($condition);
} elseif (!empty($parents)) {

View file

@ -113,9 +113,9 @@ class Compose extends BaseModule
$user = User::getById(DI::userSession()->getLocalUserId(), ['allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'default-location']);
$contact_allow_list = $this->ACLFormatter->expand($user['allow_cid']);
$group_allow_list = $this->ACLFormatter->expand($user['allow_gid']);
$circle_allow_list = $this->ACLFormatter->expand($user['allow_gid']);
$contact_deny_list = $this->ACLFormatter->expand($user['deny_cid']);
$group_deny_list = $this->ACLFormatter->expand($user['deny_gid']);
$circle_deny_list = $this->ACLFormatter->expand($user['deny_gid']);
switch ($posttype) {
case Item::PT_PERSONAL_NOTE:
@ -123,9 +123,9 @@ class Compose extends BaseModule
$type = 'note';
$doesFederate = false;
$contact_allow_list = [$a->getContactId()];
$group_allow_list = [];
$circle_allow_list = [];
$contact_deny_list = [];
$group_deny_list = [];
$circle_deny_list = [];
break;
default:
$compose_title = $this->l10n->t('Compose new post');
@ -133,19 +133,19 @@ class Compose extends BaseModule
$doesFederate = true;
$contact_allow = $_REQUEST['contact_allow'] ?? '';
$group_allow = $_REQUEST['group_allow'] ?? '';
$circle_allow = $_REQUEST['circle_allow'] ?? '';
$contact_deny = $_REQUEST['contact_deny'] ?? '';
$group_deny = $_REQUEST['group_deny'] ?? '';
$circle_deny = $_REQUEST['circle_deny'] ?? '';
if ($contact_allow
. $group_allow
. $circle_allow
. $contact_deny
. $group_deny)
. $circle_deny)
{
$contact_allow_list = $contact_allow ? explode(',', $contact_allow) : [];
$group_allow_list = $group_allow ? explode(',', $group_allow) : [];
$circle_allow_list = $circle_allow ? explode(',', $circle_allow) : [];
$contact_deny_list = $contact_deny ? explode(',', $contact_deny) : [];
$group_deny_list = $group_deny ? explode(',', $group_deny) : [];
$circle_deny_list = $circle_deny ? explode(',', $circle_deny) : [];
}
break;
@ -229,18 +229,18 @@ class Compose extends BaseModule
'$body' => $body,
'$location' => $location,
'$contact_allow'=> implode(',', $contact_allow_list),
'$group_allow' => implode(',', $group_allow_list),
'$contact_deny' => implode(',', $contact_deny_list),
'$group_deny' => implode(',', $group_deny_list),
'$contact_allow' => implode(',', $contact_allow_list),
'$circle_allow' => implode(',', $circle_allow_list),
'$contact_deny' => implode(',', $contact_deny_list),
'$circle_deny' => implode(',', $circle_deny_list),
'$jotplugins' => $jotplugins,
'$rand_num' => Crypto::randomDigits(12),
'$acl_selector' => ACL::getFullSelectorHTML($this->page, $a->getLoggedInUserId(), $doesFederate, [
'allow_cid' => $contact_allow_list,
'allow_gid' => $group_allow_list,
'allow_gid' => $circle_allow_list,
'deny_cid' => $contact_deny_list,
'deny_gid' => $group_deny_list,
'deny_gid' => $circle_deny_list,
]),
]);
}

View file

@ -35,7 +35,7 @@ use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\System;
use Friendica\Database\Database;
use Friendica\Database\DBA;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Model\Post;
use Friendica\Model\User;
use Friendica\Model\Verb;
@ -108,7 +108,7 @@ class Ping extends BaseModule
$network_count = 0;
$register_count = 0;
$sysnotify_count = 0;
$groups_unseen = [];
$circles_unseen = [];
$forums_unseen = [];
$event_count = 0;
@ -151,12 +151,12 @@ class Ping extends BaseModule
}
}
$compute_group_counts = $this->config->get('system','compute_group_counts');
if ($network_count && $compute_group_counts) {
// Find out how unseen network posts are spread across groups
foreach (Group::countUnseen() as $group_count) {
if ($group_count['count'] > 0) {
$groups_unseen[] = $group_count;
$compute_circle_counts = $this->config->get('system','compute_group_counts') ?? $this->config->get('system','compute_circle_counts');
if ($network_count && $compute_circle_counts) {
// Find out how unseen network posts are spread across circles
foreach (Circle::countUnseen() as $circle_count) {
if ($circle_count['count'] > 0) {
$circles_unseen[] = $circle_count;
}
}
@ -289,7 +289,7 @@ class Ping extends BaseModule
$data['events-today'] = $today_event_count;
$data['birthdays'] = $birthday_count;
$data['birthdays-today'] = $today_birthday_count;
$data['groups'] = $groups_unseen;
$data['circles'] = $circles_unseen;
$data['forums'] = $forums_unseen;
$data['notification'] = ($notification_count < 50) ? $notification_count : '49+';

View file

@ -27,7 +27,7 @@ use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\APContact;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Model\Item;
use Friendica\Model\Post;
use Friendica\Model\Tag;
@ -113,29 +113,29 @@ class PermissionTooltip extends \Friendica\BaseModule
exit;
}
$allowed_users = $model['allow_cid'];
$allowed_groups = $model['allow_gid'];
$deny_users = $model['deny_cid'];
$deny_groups = $model['deny_gid'];
$allowed_users = $model['allow_cid'];
$allowed_circles = $model['allow_gid'];
$deny_users = $model['deny_cid'];
$deny_circles = $model['deny_gid'];
$o = DI::l10n()->t('Visible to:') . '<br />';
$l = [];
if (count($allowed_groups)) {
$key = array_search(Group::FOLLOWERS, $allowed_groups);
if (count($allowed_circles)) {
$key = array_search(Circle::FOLLOWERS, $allowed_circles);
if ($key !== false) {
$l[] = '<b>' . DI::l10n()->t('Followers') . '</b>';
unset($allowed_groups[$key]);
unset($allowed_circles[$key]);
}
$key = array_search(Group::MUTUALS, $allowed_groups);
$key = array_search(Circle::MUTUALS, $allowed_circles);
if ($key !== false) {
$l[] = '<b>' . DI::l10n()->t('Mutuals') . '</b>';
unset($allowed_groups[$key]);
unset($allowed_circles[$key]);
}
foreach (DI::dba()->selectToArray('group', ['name'], ['id' => $allowed_groups]) as $group) {
$l[] = '<b>' . $group['name'] . '</b>';
foreach (DI::dba()->selectToArray('group', ['name'], ['id' => $allowed_circles]) as $circle) {
$l[] = '<b>' . $circle['name'] . '</b>';
}
}
@ -143,21 +143,21 @@ class PermissionTooltip extends \Friendica\BaseModule
$l[] = $contact['name'];
}
if (count($deny_groups)) {
$key = array_search(Group::FOLLOWERS, $deny_groups);
if (count($deny_circles)) {
$key = array_search(Circle::FOLLOWERS, $deny_circles);
if ($key !== false) {
$l[] = '<b><strike>' . DI::l10n()->t('Followers') . '</strike></b>';
unset($deny_groups[$key]);
unset($deny_circles[$key]);
}
$key = array_search(Group::MUTUALS, $deny_groups);
$key = array_search(Circle::MUTUALS, $deny_circles);
if ($key !== false) {
$l[] = '<b><strike>' . DI::l10n()->t('Mutuals') . '</strike></b>';
unset($deny_groups[$key]);
unset($deny_circles[$key]);
}
foreach (DI::dba()->selectToArray('group', ['name'], ['id' => $allowed_groups]) as $group) {
$l[] = '<b><strike>' . $group['name'] . '</strike></b>';
foreach (DI::dba()->selectToArray('group', ['name'], ['id' => $allowed_circles]) as $circle) {
$l[] = '<b><strike>' . $circle['name'] . '</strike></b>';
}
}

View file

@ -165,7 +165,7 @@ class Conversations extends BaseProfile
$o .= $this->conversation->statusEditor($x);
}
// Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
// Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched their circles
$condition = Item::getPermissionsConditionArrayByUserId($profile['uid']);
$last_updated_array = $this->session->get('last_updated', []);

View file

@ -93,14 +93,14 @@ class Photos extends \Friendica\Module\BaseProfile
}
$str_contact_allow = isset($request['contact_allow']) ? $this->aclFormatter->toString($request['contact_allow']) : $this->owner['allow_cid'] ?? '';
$str_group_allow = isset($request['group_allow']) ? $this->aclFormatter->toString($request['group_allow']) : $this->owner['allow_gid'] ?? '';
$str_circle_allow = isset($request['circle_allow']) ? $this->aclFormatter->toString($request['circle_allow']) : $this->owner['allow_gid'] ?? '';
$str_contact_deny = isset($request['contact_deny']) ? $this->aclFormatter->toString($request['contact_deny']) : $this->owner['deny_cid'] ?? '';
$str_group_deny = isset($request['group_deny']) ? $this->aclFormatter->toString($request['group_deny']) : $this->owner['deny_gid'] ?? '';
$str_circle_deny = isset($request['circle_deny']) ? $this->aclFormatter->toString($request['circle_deny']) : $this->owner['deny_gid'] ?? '';
$visibility = $request['visibility'] ?? '';
if ($visibility === 'public') {
// The ACL selector introduced in version 2019.12 sends ACL input data even when the Public visibility is selected
$str_contact_allow = $str_group_allow = $str_contact_deny = $str_group_deny = '';
$str_contact_allow = $str_circle_allow = $str_contact_deny = $str_circle_deny = '';
} else if ($visibility === 'custom') {
// Since we know from the visibility parameter the item should be private, we have to prevent the empty ACL
// case that would make it public. So we always append the author's contact id to the allowed contacts.
@ -231,7 +231,7 @@ class Photos extends \Friendica\Module\BaseProfile
$resource_id = Photo::newResource();
$preview = Photo::storeWithPreview($image, $this->owner['uid'], $resource_id, $filename, $filesize, $album, '', $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
$preview = Photo::storeWithPreview($image, $this->owner['uid'], $resource_id, $filename, $filesize, $album, '', $str_contact_allow, $str_circle_allow, $str_contact_deny, $str_circle_deny);
if ($preview < 0) {
$this->logger->warning('image store failed');
$this->systemMessages->addNotice($this->t('Image upload failed.'));
@ -267,9 +267,9 @@ class Photos extends \Friendica\Module\BaseProfile
$arr['author-avatar'] = $this->owner['thumb'];
$arr['title'] = '';
$arr['allow_cid'] = $str_contact_allow;
$arr['allow_gid'] = $str_group_allow;
$arr['allow_gid'] = $str_circle_allow;
$arr['deny_cid'] = $str_contact_deny;
$arr['deny_gid'] = $str_group_deny;
$arr['deny_gid'] = $str_circle_deny;
$arr['visible'] = $visible;
$arr['origin'] = 1;

View file

@ -46,13 +46,13 @@ use Psr\Log\LoggerInterface;
*/
class Acl extends BaseModule
{
const TYPE_GLOBAL_CONTACT = 'x';
const TYPE_MENTION_CONTACT = 'c';
const TYPE_MENTION_GROUP = 'g';
const TYPE_MENTION_CONTACT_GROUP = '';
const TYPE_MENTION_FORUM = 'f';
const TYPE_PRIVATE_MESSAGE = 'm';
const TYPE_ANY_CONTACT = 'a';
const TYPE_GLOBAL_CONTACT = 'x';
const TYPE_MENTION_CONTACT = 'c';
const TYPE_MENTION_CIRCLE = 'g';
const TYPE_MENTION_CONTACT_CIRCLE = '';
const TYPE_MENTION_FORUM = 'f';
const TYPE_PRIVATE_MESSAGE = 'm';
const TYPE_ANY_CONTACT = 'a';
/** @var IHandleUserSessions */
private $session;
@ -73,7 +73,7 @@ class Acl extends BaseModule
throw new HTTPException\UnauthorizedException($this->t('You must be logged in to use this module.'));
}
$type = $request['type'] ?? self::TYPE_MENTION_CONTACT_GROUP;
$type = $request['type'] ?? self::TYPE_MENTION_CONTACT_CIRCLE;
if ($type === self::TYPE_GLOBAL_CONTACT) {
$o = $this->globalContactSearch($request);
} else {
@ -128,28 +128,28 @@ class Acl extends BaseModule
$this->logger->info('ACL {action} - {subaction} - start', ['module' => 'acl', 'action' => 'content', 'subaction' => 'search', 'search' => $search, 'type' => $type, 'conversation' => $conv_id]);
$sql_extra = '';
$condition = ["`uid` = ? AND NOT `deleted` AND NOT `pending` AND NOT `archive`", $this->session->getLocalUserId()];
$condition_group = ["`uid` = ? AND NOT `deleted`", $this->session->getLocalUserId()];
$sql_extra = '';
$condition = ["`uid` = ? AND NOT `deleted` AND NOT `pending` AND NOT `archive`", $this->session->getLocalUserId()];
$condition_circle = ["`uid` = ? AND NOT `deleted`", $this->session->getLocalUserId()];
if ($search != '') {
$sql_extra = "AND `name` LIKE '%%" . $this->database->escape($search) . "%%'";
$condition = DBA::mergeConditions($condition, ["(`attag` LIKE ? OR `name` LIKE ? OR `nick` LIKE ?)",
$sql_extra = "AND `name` LIKE '%%" . $this->database->escape($search) . "%%'";
$condition = DBA::mergeConditions($condition, ["(`attag` LIKE ? OR `name` LIKE ? OR `nick` LIKE ?)",
'%' . $search . '%', '%' . $search . '%', '%' . $search . '%']);
$condition_group = DBA::mergeConditions($condition_group, ["`name` LIKE ?", '%' . $search . '%']);
$condition_circle = DBA::mergeConditions($condition_circle, ["`name` LIKE ?", '%' . $search . '%']);
}
// count groups and contacts
$group_count = 0;
if ($type == self::TYPE_MENTION_CONTACT_GROUP || $type == self::TYPE_MENTION_GROUP) {
$group_count = $this->database->count('group', $condition_group);
// count circles and contacts
$circle_count = 0;
if ($type == self::TYPE_MENTION_CONTACT_CIRCLE || $type == self::TYPE_MENTION_CIRCLE) {
$circle_count = $this->database->count('group', $condition_circle);
}
$networks = Widget::unavailableNetworks();
$condition = DBA::mergeConditions($condition, array_merge(["NOT `network` IN (" . substr(str_repeat("?, ", count($networks)), 0, -2) . ")"], $networks));
switch ($type) {
case self::TYPE_MENTION_CONTACT_GROUP:
case self::TYPE_MENTION_CONTACT_CIRCLE:
$condition = DBA::mergeConditions($condition,
["NOT `self` AND NOT `blocked` AND `notify` != ? AND `network` != ?", '', Protocol::OSTATUS
]);
@ -176,52 +176,52 @@ class Acl extends BaseModule
$contact_count = $this->database->count('contact', $condition);
$resultTotal = $group_count + $contact_count;
$resultTotal = $circle_count + $contact_count;
$resultGroups = [];
$resultCircles = [];
$resultContacts = [];
if ($type == self::TYPE_MENTION_CONTACT_GROUP || $type == self::TYPE_MENTION_GROUP) {
if ($type == self::TYPE_MENTION_CONTACT_CIRCLE || $type == self::TYPE_MENTION_CIRCLE) {
/// @todo We should cache this query.
// This can be done when we can delete cache entries via wildcard
$groups = $this->database->toArray($this->database->p("SELECT `group`.`id`, `group`.`name`, GROUP_CONCAT(DISTINCT `group_member`.`contact-id` SEPARATOR ',') AS uids
FROM `group`
INNER JOIN `group_member` ON `group_member`.`gid`=`group`.`id`
WHERE NOT `group`.`deleted` AND `group`.`uid` = ?
$circles = $this->database->toArray($this->database->p("SELECT `circle`.`id`, `circle`.`name`, GROUP_CONCAT(DISTINCT `circle_member`.`contact-id` SEPARATOR ',') AS uids
FROM `group` AS `circle`
INNER JOIN `group_member` AS `circle_member` ON `circle_member`.`gid` = `circle`.`id`
WHERE NOT `circle`.`deleted` AND `circle`.`uid` = ?
$sql_extra
GROUP BY `group`.`name`, `group`.`id`
ORDER BY `group`.`name`
GROUP BY `circle`.`name`, `circle`.`id`
ORDER BY `circle`.`name`
LIMIT ?, ?",
$this->session->getLocalUserId(),
$start,
$count
));
foreach ($groups as $group) {
$resultGroups[] = [
'type' => 'g',
foreach ($circles as $circle) {
$resultCircles[] = [
'type' => self::TYPE_MENTION_CIRCLE,
'photo' => 'images/twopeople.png',
'name' => htmlspecialchars($group['name']),
'id' => intval($group['id']),
'uids' => array_map('intval', explode(',', $group['uids'])),
'name' => htmlspecialchars($circle['name']),
'id' => intval($circle['id']),
'uids' => array_map('intval', explode(',', $circle['uids'])),
'link' => '',
'forum' => '0'
];
}
if ((count($resultGroups) > 0) && ($search == '')) {
$resultGroups[] = ['separator' => true];
if ((count($resultCircles) > 0) && ($search == '')) {
$resultCircles[] = ['separator' => true];
}
}
$contacts = [];
if ($type != self::TYPE_MENTION_GROUP) {
if ($type != self::TYPE_MENTION_CIRCLE) {
$contacts = Contact::selectToArray([], $condition, ['order' => ['name']]);
}
$forums = [];
foreach ($contacts as $contact) {
$entry = [
'type' => 'c',
'type' => self::TYPE_MENTION_CONTACT,
'photo' => Contact::getMicro($contact, true),
'name' => htmlspecialchars($contact['name']),
'id' => intval($contact['id']),
@ -246,7 +246,7 @@ class Acl extends BaseModule
$resultContacts = array_merge($forums, $resultContacts);
}
$resultItems = array_merge($resultGroups, $resultContacts);
$resultItems = array_merge($resultCircles, $resultContacts);
if ($conv_id) {
// In multithreaded posts the conv_id is not the parent of the whole thread
@ -277,7 +277,7 @@ class Acl extends BaseModule
$contact = Contact::getByURL($author, false, ['micro', 'name', 'id', 'network', 'nick', 'addr', 'url', 'forum', 'avatar']);
if ($contact) {
$unknown_contacts[] = [
'type' => 'c',
'type' => self::TYPE_MENTION_CONTACT,
'photo' => Contact::getMicro($contact, true),
'name' => htmlspecialchars($contact['name']),
'id' => intval($contact['id']),
@ -298,7 +298,7 @@ class Acl extends BaseModule
'tot' => $resultTotal,
'start' => $start,
'count' => $count,
'groups' => $resultGroups,
'circles' => $resultCircles,
'contacts' => $resultContacts,
'items' => $resultItems,
'type' => $type,

View file

@ -29,7 +29,7 @@ use Friendica\Core\Search;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Model\Notification;
use Friendica\Model\Post\UserNotification;
use Friendica\Model\Profile;
@ -162,23 +162,23 @@ class Account extends BaseSettings
$blocktags = empty($request['blocktags']); // this setting is inverted!
$unkmail = !empty($request['unkmail']);
$cntunkmail = intval($request['cntunkmail'] ?? 0);
$def_gid = intval($request['group-selection'] ?? 0);
$def_gid = intval($request['circle-selection'] ?? 0);
$aclFormatter = DI::aclFormatter();
$str_group_allow = !empty($request['group_allow']) ? $aclFormatter->toString($request['group_allow']) : '';
$str_contact_allow = !empty($request['contact_allow']) ? $aclFormatter->toString($request['contact_allow']) : '';
$str_group_deny = !empty($request['group_deny']) ? $aclFormatter->toString($request['group_deny']) : '';
$str_contact_deny = !empty($request['contact_deny']) ? $aclFormatter->toString($request['contact_deny']) : '';
$str_circle_allow = !empty($request['circle_allow']) ? $aclFormatter->toString($request['circle_allow']) : '';
$str_contact_deny = !empty($request['contact_deny']) ? $aclFormatter->toString($request['contact_deny']) : '';
$str_circle_deny = !empty($request['circle_deny']) ? $aclFormatter->toString($request['circle_deny']) : '';
DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'system', 'unlisted', !empty($request['unlisted']));
DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'system', 'accessible-photos', !empty($request['accessible-photos']));
$fields = [
'allow_cid' => $str_contact_allow,
'allow_gid' => $str_group_allow,
'allow_gid' => $str_circle_allow,
'deny_cid' => $str_contact_deny,
'deny_gid' => $str_group_deny,
'deny_gid' => $str_circle_deny,
'maxreq' => $maxreq,
'def_gid' => $def_gid,
'blockwall' => $blockwall,
@ -329,7 +329,7 @@ class Account extends BaseSettings
$fields = [
'allow_cid' => '',
'allow_gid' => $page_flags == User::PAGE_FLAGS_PRVGROUP ?
'<' . Group::FOLLOWERS . '>'
'<' . Circle::FOLLOWERS . '>'
: '',
'deny_cid' => '',
'deny_gid' => '',
@ -592,7 +592,7 @@ class Account extends BaseSettings
'$blocktags' => ['blocktags', DI::l10n()->t('Allow friends to tag your posts?'), (intval($user['blocktags']) ? '0' : '1'), DI::l10n()->t('Your contacts can add additional tags to your posts.')],
'$unkmail' => ['unkmail', DI::l10n()->t('Permit unknown people to send you private mail?'), $unkmail, DI::l10n()->t('Friendica network users may send you private messages even if they are not in your contact list.')],
'$cntunkmail' => ['cntunkmail', DI::l10n()->t('Maximum private messages per day from unknown people:'), $cntunkmail, DI::l10n()->t("(to prevent spam abuse)")],
'$group_select' => Group::displayGroupSelection(DI::userSession()->getLocalUserId(), $user['def_gid']),
'$circle_select' => Circle::getSelectorHTML(DI::userSession()->getLocalUserId(), $user['def_gid']),
'$permissions' => DI::l10n()->t('Default Post Permissions'),
'$aclselect' => ACL::getFullSelectorHTML(DI::page(), $a->getLoggedInUserId()),

View file

@ -260,7 +260,7 @@ class Index extends BaseSettings
<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>",
<p>Non-public fields can only be seen by the selected Friendica contacts or the Friendica contacts in the selected circles.</p>",
'profile/' . $profile['nickname'] . '/profile'
),
'$custom_fields' => $custom_fields,
@ -284,9 +284,9 @@ class Index extends BaseSettings
$permissionSet = DI::permissionSet()->selectOrCreate(DI::permissionSetFactory()->createFromString(
$uid,
DI::aclFormatter()->toString($profileFieldInputs['new']['contact_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInputs['new']['group_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInputs['new']['circle_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInputs['new']['contact_deny'] ?? ''),
DI::aclFormatter()->toString($profileFieldInputs['new']['group_deny'] ?? '')
DI::aclFormatter()->toString($profileFieldInputs['new']['circle_deny'] ?? '')
));
$profileFields->append(DI::profileFieldFactory()->createFromValues(
@ -305,9 +305,9 @@ class Index extends BaseSettings
$permissionSet = DI::permissionSet()->selectOrCreate(DI::permissionSetFactory()->createFromString(
$uid,
DI::aclFormatter()->toString($profileFieldInput['contact_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInput['group_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInput['circle_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInput['contact_deny'] ?? ''),
DI::aclFormatter()->toString($profileFieldInput['group_deny'] ?? '')
DI::aclFormatter()->toString($profileFieldInput['circle_deny'] ?? '')
));
$profileFields->append(DI::profileFieldFactory()->createFromValues(

View file

@ -263,12 +263,12 @@ class UserExport extends BaseSettings
sprintf("SELECT * FROM `pconfig` WHERE uid = %d", $user_id)
);
$group = $this->exportMultiRow(
$circle = $this->exportMultiRow(
sprintf("SELECT * FROM `group` WHERE uid = %d", $user_id)
);
$group_member = $this->exportMultiRow(
sprintf("SELECT `group_member`.`gid`, `group_member`.`contact-id` FROM `group_member` INNER JOIN `group` ON `group`.`id` = `group_member`.`gid` WHERE `group`.`uid` = %d", $user_id)
$circle_member = $this->exportMultiRow(
sprintf("SELECT `circle_member`.`gid`, `circle_member`.`contact-id` FROM `group_member` AS `circle_member` INNER JOIN `group` AS `circle` ON `circle`.`id` = `circle_member`.`gid` WHERE `circle`.`uid` = %d", $user_id)
);
$output = [
@ -281,8 +281,8 @@ class UserExport extends BaseSettings
'profile_fields' => $profile_fields,
'photo' => $photo,
'pconfig' => $pconfig,
'group' => $group,
'group_member' => $group_member,
'circle' => $circle,
'circle_member' => $circle_member,
];
echo json_encode($output, JSON_PARTIAL_OUTPUT_ON_ERROR);

View file

@ -63,7 +63,7 @@ class Profile extends BaseModule
System::htmlUpdateExit($o);
}
// Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
// Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched their circles
$sql_extra = Item::getPermissionsSQLByUserId($a->getProfileOwner());
$last_updated_array = DI::session()->get('last_updated', []);

View file

@ -231,6 +231,10 @@ class Import extends \Friendica\BaseModule
return;
}
// Backward compatibility
$account['circle'] = $account['circle'] ?? $account['group'];
$account['circle_member'] = $account['circle_member'] ?? $account['group_member'];
$oldBaseUrl = $account['baseurl'];
$newBaseUrl = (string)$this->baseUrl;
@ -312,35 +316,35 @@ class Import extends \Friendica\BaseModule
$this->systemMessages->addNotice($this->tt('%d contact not imported', '%d contacts not imported', $errorCount));
}
array_walk($account['group'], function (&$group) use ($newUid) {
$group['uid'] = $newUid;
if ($this->dbImportAssoc('group', $group) === false) {
$this->logger->warning('Error inserting group', ['name' => $group['name'], 'error' => $this->database->errorMessage()]);
array_walk($account['circle'], function (&$circle) use ($newUid) {
$circle['uid'] = $newUid;
if ($this->dbImportAssoc('group', $circle) === false) {
$this->logger->warning('Error inserting circle', ['name' => $circle['name'], 'error' => $this->database->errorMessage()]);
} else {
$group['newid'] = $this->lastInsertId();
$circle['newid'] = $this->lastInsertId();
}
});
foreach ($account['group_member'] as $group_member) {
foreach ($account['circle_member'] as $circle_member) {
$import = 0;
foreach ($account['group'] as $group) {
if ($group['id'] == $group_member['gid'] && isset($group['newid'])) {
$group_member['gid'] = $group['newid'];
foreach ($account['circle'] as $circle) {
if ($circle['id'] == $circle_member['gid'] && isset($circle['newid'])) {
$circle_member['gid'] = $circle['newid'];
$import++;
break;
}
}
foreach ($account['contact'] as $contact) {
if ($contact['id'] == $group_member['contact-id'] && isset($contact['newid'])) {
$group_member['contact-id'] = $contact['newid'];
if ($contact['id'] == $circle_member['contact-id'] && isset($contact['newid'])) {
$circle_member['contact-id'] = $contact['newid'];
$import++;
break;
}
}
if ($import == 2 && $this->dbImportAssoc('group_member', $group_member) === false) {
$this->logger->warning('Error inserting group member', ['gid' => $group_member['id'], 'error' => $this->database->errorMessage()]);
if ($import == 2 && $this->dbImportAssoc('group_member', $circle_member) === false) {
$this->logger->warning('Error inserting circle member', ['gid' => $circle_member['id'], 'error' => $this->database->errorMessage()]);
}
}

View file

@ -73,9 +73,9 @@ class Welcome extends BaseModule
'$finding_link' => DI::l10n()->t('Finding New People'),
'$finding_txt' => DI::l10n()->t('On the side panel of the Contacts page are several tools to find new friends. We can match people by interest, look up people by name or interest, and provide suggestions based on network relationships. On a brand new site, friend suggestions will usually begin to be populated within 24 hours.'),
'$groups' => DI::l10n()->t('Groups'),
'$group_contact_link' => DI::l10n()->t('Group Your Contacts'),
'$group_contact_txt' => DI::l10n()->t('Once you have made some friends, organize them into private conversation groups from the sidebar of your Contacts page and then you can interact with each group privately on your Network page.'),
'$circles' => DI::l10n()->t('Circles'),
'$circle_contact_link' => DI::l10n()->t('Add Your Contacts To Circle'),
'$circle_contact_txt' => DI::l10n()->t('Once you have made some friends, organize them into private conversation circles from the sidebar of your Contacts page and then you can interact with each circle privately on your Network page.'),
'$newuser_private' => $newuser_private,
'$private_link' => DI::l10n()->t('Why Aren\'t My Posts Public?'),
'$private_txt' => DI::l10n()->t('Friendica respects your privacy. By default, your posts will only show up to people you\'ve added as friends. For more information, see the help section from the link above.'),

View file

@ -23,12 +23,7 @@ namespace Friendica\Object\Api\Friendica;
use Friendica\BaseDataTransferObject;
/**
* Class Group
*
*
*/
class Group extends BaseDataTransferObject
class Circle extends BaseDataTransferObject
{
/** @var string */
protected $name;
@ -42,18 +37,16 @@ class Group extends BaseDataTransferObject
protected $mode;
/**
* Creates an Group entity array
*
* @param array $group
* @param array $circle Circle row array
* @param array $user
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public function __construct(array $group, array $user)
public function __construct(array $circle, array $user)
{
$this->name = $group['name'];
$this->id = $group['id'];
$this->id_str = (string)$group['id'];
$this->name = $circle['name'];
$this->id = $circle['id'];
$this->id_str = (string)$circle['id'];
$this->user = $user;
$this->mode = $group['visible'] ? 'public' : 'private';
$this->mode = $circle['visible'] ? 'public' : 'private';
}
}

View file

@ -28,7 +28,7 @@ use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\APContact;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Model\Item;
use Friendica\Model\Post;
use Friendica\Model\User;
@ -284,7 +284,7 @@ class ClientToServer
$item['private'] = Item::UNLISTED;
} elseif (!empty($object_data['target'][Receiver::TARGET_FOLLOWER])) {
$item['allow_cid'] = '';
$item['allow_gid'] = '<' . Group::FOLLOWERS . '>';
$item['allow_gid'] = '<' . Circle::FOLLOWERS . '>';
$item['deny_cid'] = '';
$item['deny_gid'] = '';
$item['private'] = Item::PRIVATE;

View file

@ -1098,7 +1098,7 @@ class Receiver
if (!empty($actor)) {
$profile = APContact::getByURL($actor);
$followers = $profile['followers'] ?? '';
$is_forum = ($actor['type'] ?? '') == 'Group';
$is_forum = ($profile['type'] ?? '') == 'Group';
if ($push) {
Contact::updateByUrlIfNeeded($actor);
}

View file

@ -25,7 +25,7 @@ use Exception;
use Friendica\BaseRepository;
use Friendica\Database\Database;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Network\HTTPException\NotFoundException;
use Friendica\Security\PermissionSet\Exception\PermissionSetNotFoundException;
use Friendica\Security\PermissionSet\Exception\PermissionSetPersistenceException;
@ -140,29 +140,29 @@ class PermissionSet extends BaseRepository
$user_contact_str = '';
}
$groups = [];
$circle_ids = [];
if (!empty($user_contact_str) && $this->db->exists('contact', [
'id' => $cid,
'uid' => $uid,
'blocked' => false
])) {
$groups = Group::getIdsByContactId($cid);
$circle_ids = Circle::getIdsByContactId($cid);
}
$group_str = '<<>>'; // should be impossible to match
foreach ($groups as $group_id) {
$group_str .= '|<' . preg_quote($group_id) . '>';
$circle_str = '<<>>'; // should be impossible to match
foreach ($circle_ids as $circle_id) {
$circle_str .= '|<' . preg_quote($circle_id) . '>';
}
if (!empty($user_contact_str)) {
$condition = ["`uid` = ? AND (NOT (LOCATE(?, `deny_cid`) OR LOCATE(?, `deny_cid`) OR deny_gid REGEXP ?)
AND (LOCATE(?, allow_cid) OR LOCATE(?, allow_cid) OR allow_gid REGEXP ? OR (allow_cid = '' AND allow_gid = '')))",
$uid, $user_contact_str, $public_contact_str, $group_str,
$user_contact_str, $public_contact_str, $group_str];
$uid, $user_contact_str, $public_contact_str, $circle_str,
$user_contact_str, $public_contact_str, $circle_str];
} else {
$condition = ["`uid` = ? AND (NOT (LOCATE(?, `deny_cid`) OR deny_gid REGEXP ?)
AND (LOCATE(?, allow_cid) OR allow_gid REGEXP ? OR (allow_cid = '' AND allow_gid = '')))",
$uid, $public_contact_str, $group_str, $public_contact_str, $group_str];
$uid, $public_contact_str, $circle_str, $public_contact_str, $circle_str];
}
return $this->select($condition);

View file

@ -24,7 +24,7 @@ namespace Friendica\Security;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Model\User;
/**
@ -117,17 +117,13 @@ class Security
if ($local_user && $local_user == $owner_id) {
$sql = '';
/*
* Authenticated visitor. Load the groups the visitor belongs to.
* Authenticated visitor. Load the circles the visitor belongs to.
*/
} elseif ($remote_contact) {
$gs = '<<>>'; // should be impossible to match
$circleIds = '<<>>'; // should be impossible to match
$groups = Group::getIdsByContactId($remote_contact);
if (is_array($groups)) {
foreach ($groups as $g) {
$gs .= '|<' . intval($g) . '>';
}
foreach (Circle::getIdsByContactId($remote_contact) as $circleId) {
$circleIds .= '|<' . intval($circleId) . '>';
}
$sql = sprintf(
@ -135,9 +131,9 @@ class Security
AND (allow_cid REGEXP '<%d>' OR allow_gid REGEXP '%s'
OR (allow_cid = '' AND allow_gid = ''))" . $acc_sql . ") ",
intval($remote_contact),
DBA::escape($gs),
DBA::escape($circleIds),
intval($remote_contact),
DBA::escape($gs)
DBA::escape($circleIds)
);
}
return $sql;

View file

@ -21,7 +21,7 @@
namespace Friendica\Util;
use Friendica\Model\Group;
use Friendica\Model\Circle;
/**
* Util class for ACL formatting
@ -29,7 +29,7 @@ use Friendica\Model\Group;
final class ACLFormatter
{
/**
* Turn user/group ACLs stored as angle bracketed text into arrays
* Turn user/circle ACLs stored as angle bracketed text into arrays
*
* @param string|null $acl_string A angle-bracketed list of IDs
*
@ -44,7 +44,7 @@ final class ACLFormatter
// turn string array of angle-bracketed elements into numeric array
// e.g. "<1><2><3>" => array(1,2,3);
preg_match_all('/<(' . Group::FOLLOWERS . '|'. Group::MUTUALS . '|[0-9]+)>/', $acl_string, $matches, PREG_PATTERN_ORDER);
preg_match_all('/<(' . Circle::FOLLOWERS . '|'. Circle::MUTUALS . '|[0-9]+)>/', $acl_string, $matches, PREG_PATTERN_ORDER);
return $matches[1];
}
@ -86,7 +86,7 @@ final class ACLFormatter
if (intval($item)) {
$item = '<' . intval($item) . '>';
// The item is a allowed ACL character
} elseif (in_array($item, [Group::FOLLOWERS, Group::MUTUALS])) {
} elseif (in_array($item, [Circle::FOLLOWERS, Circle::MUTUALS])) {
$item = '<' . $item . '>';
// The item is already a ACL string
} elseif (preg_match('/<\d+?>/', $item)) {

View file

@ -29,7 +29,7 @@ use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Conversation;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Model\GServer;
use Friendica\Model\Item;
use Friendica\Model\Post;
@ -340,9 +340,9 @@ class Notifier
$aclFormatter = DI::aclFormatter();
$allow_people = $aclFormatter->expand($parent['allow_cid']);
$allow_groups = Group::expand($uid, $aclFormatter->expand($parent['allow_gid']),true);
$allow_circles = Circle::expand($uid, $aclFormatter->expand($parent['allow_gid']),true);
$deny_people = $aclFormatter->expand($parent['deny_cid']);
$deny_groups = Group::expand($uid, $aclFormatter->expand($parent['deny_gid']));
$deny_circles = Circle::expand($uid, $aclFormatter->expand($parent['deny_gid']));
foreach ($items as $item) {
$recipients[] = $item['contact-id'];
@ -363,8 +363,8 @@ class Notifier
Logger::notice('Deliver', ['target' => $target_id, 'guid' => $target_item['guid'], 'recipients' => $url_recipients]);
}
$recipients = array_unique(array_merge($recipients, $allow_people, $allow_groups));
$deny = array_unique(array_merge($deny_people, $deny_groups));
$recipients = array_unique(array_merge($recipients, $allow_people, $allow_circles));
$deny = array_unique(array_merge($deny_people, $deny_circles));
$recipients = array_diff($recipients, $deny);
// If this is a public message and pubmail is set on the parent, include all your email contacts
@ -797,7 +797,7 @@ class Notifier
foreach (Tag::getByURIId($target_item['uri-id'], [Tag::MENTION, Tag::EXCLUSIVE_MENTION]) as $tag) {
$target_contact = Contact::getByURL(Strings::normaliseLink($tag['url']), null, [], $uid);
if ($target_contact && $target_contact['contact-type'] == Contact::TYPE_COMMUNITY && $target_contact['manually-approve']) {
Group::updateMembersForForum($target_contact['id']);
Circle::updateMembersForForum($target_contact['id']);
}
}

View file

@ -311,9 +311,9 @@ return [
"id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "foreign" => ["user" => "uid"], "comment" => "Owner id of this permission set"],
"allow_cid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed contact.id '<19><78>'"],
"allow_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed groups"],
"allow_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed circles"],
"deny_cid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied contact.id"],
"deny_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied groups"],
"deny_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied circles"],
],
"indexes" => [
"PRIMARY" => ["id"],
@ -513,9 +513,9 @@ return [
"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"],
"allow_cid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed contact.id '<19><78>"],
"allow_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed groups"],
"allow_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed circles"],
"deny_cid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied contact.id"],
"deny_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied groups"],
"deny_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied circles"],
"backend-class" => ["type" => "tinytext", "comment" => "Storage backend class"],
"backend-ref" => ["type" => "text", "comment" => "Storage backend data reference"],
],
@ -715,9 +715,9 @@ return [
"nofinish" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "if event does have no end this is 1"],
"ignore" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "0 or 1"],
"allow_cid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed contact.id '<19><78>'"],
"allow_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed groups"],
"allow_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed circles"],
"deny_cid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied contact.id"],
"deny_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied groups"],
"deny_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied circles"],
],
"indexes" => [
"PRIMARY" => ["id"],
@ -760,14 +760,14 @@ return [
]
],
"group" => [
"comment" => "privacy groups, group info",
"comment" => "privacy circles, circle info",
"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", "foreign" => ["user" => "uid"], "comment" => "Owner User id"],
"visible" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "1 indicates the member list is not private"],
"deleted" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "1 indicates the group has been deleted"],
"deleted" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "1 indicates the circle has been deleted"],
"cid" => ["type" => "int unsigned", "foreign" => ["contact" => "id"], "comment" => "Contact id of forum. When this field is filled then the members are synced automatically."],
"name" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "human readable name of group"],
"name" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "human readable name of circle"],
],
"indexes" => [
"PRIMARY" => ["id"],
@ -776,11 +776,11 @@ return [
]
],
"group_member" => [
"comment" => "privacy groups, member info",
"comment" => "privacy circles, member info",
"fields" => [
"id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
"gid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["group" => "id"], "comment" => "groups.id of the associated group"],
"contact-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "comment" => "contact.id of the member assigned to the associated group"],
"gid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["group" => "id"], "comment" => "group.id of the associated circle"],
"contact-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id"], "comment" => "contact.id of the member assigned to the associated circle"],
],
"indexes" => [
"PRIMARY" => ["id"],
@ -1150,9 +1150,9 @@ return [
"scale" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => ""],
"profile" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
"allow_cid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed contact.id '<19><78>'"],
"allow_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed groups"],
"allow_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed circles"],
"deny_cid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied contact.id"],
"deny_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied groups"],
"deny_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of denied circles"],
"accessible" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Make photo publicly accessible, ignoring permissions"],
"backend-class" => ["type" => "tinytext", "comment" => "Storage backend class"],
"backend-ref" => ["type" => "text", "comment" => "Storage backend data reference"],

View file

@ -310,10 +310,10 @@ return [
// Number of "free" searches when system => permit_crawling is enabled.
'free_crawls' => 10,
// groupedit_image_limit (Integer)
// Number of contacts at which the group editor should switch from display the profile pictures of the contacts to only display the names.
// circle_edit_image_limit (Integer)
// Number of contacts at which the circle editor should switch from display the profile pictures of the contacts to only display the names.
// This can alternatively be set on a per-account basis in the pconfig table.
'groupedit_image_limit' => 400,
'circle_edit_image_limit' => 400,
// gserver_update_limit (Integer)
// How many servers should be checked at a time?

View file

@ -89,12 +89,20 @@ $apiRoutes = [
'/direct_messages_setseen[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\DirectMessages\Setseen::class, [ R::POST]],
'/direct_messages_search[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\DirectMessages\Search ::class, [R::GET ]],
'/events[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Events\Index::class, [R::GET ]],
'/event_create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Events\Create::class, [ R::POST]],
'/event_delete[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Events\Delete::class, [ R::POST]],
'/group_show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Group\Show::class, [R::GET ]],
'/group_create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Group\Create::class, [ R::POST]],
'/group_delete[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Group\Delete::class, [ R::POST]],
'/group_update[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Group\Update::class, [ R::POST]],
'/event_create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Events\Create::class, [ R::POST]],
'/event_delete[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Events\Delete::class, [ R::POST]],
'/circle_show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Circle\Show::class, [R::GET ]],
'/circle_create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Circle\Create::class, [ R::POST]],
'/circle_delete[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Circle\Delete::class, [ R::POST]],
'/circle_update[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Circle\Update::class, [ R::POST]],
// Backward compatibility
// @deprecated
'/group_show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Circle\Show::class, [R::GET ]],
'/group_create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Circle\Create::class, [ R::POST]],
'/group_delete[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Circle\Delete::class, [ R::POST]],
'/group_update[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Circle\Update::class, [ R::POST]],
'/profile/show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Profile\Show::class, [R::GET ]],
'/photoalbums[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Photoalbum\Index::class, [R::GET ]],
'/photoalbum[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Photoalbum\Show::class, [R::GET ]],
@ -446,14 +454,14 @@ return [
'/fsuggest/{contact:\d+}' => [Module\FriendSuggest::class, [R::GET, R::POST]],
'/group' => [
'[/]' => [Module\Group::class, [R::GET, R::POST]],
'/{group:\d+}' => [Module\Group::class, [R::GET, R::POST]],
'/none' => [Module\Group::class, [R::GET, R::POST]],
'/new' => [Module\Group::class, [R::GET, R::POST]],
'/drop/{group:\d+}' => [Module\Group::class, [R::GET, R::POST]],
'/{group:\d+}/{contact:\d+}' => [Module\Group::class, [R::GET, R::POST]],
'/{group:\d+}/{command:add|remove}/{contact:\d+}' => [Module\Group::class, [R::GET, R::POST]],
'/circle' => [
'[/]' => [Module\Circle::class, [R::GET, R::POST]],
'/{circle:\d+}' => [Module\Circle::class, [R::GET, R::POST]],
'/none' => [Module\Circle::class, [R::GET, R::POST]],
'/new' => [Module\Circle::class, [R::GET, R::POST]],
'/drop/{circle:\d+}' => [Module\Circle::class, [R::GET, R::POST]],
'/{circle:\d+}/{contact:\d+}' => [Module\Circle::class, [R::GET, R::POST]],
'/{circle:\d+}/{command:add|remove}/{contact:\d+}' => [Module\Circle::class, [R::GET, R::POST]],
],
'/hashtag' => [Module\Hashtag::class, [R::GET]],
'/help[/{doc:.+}]' => [Module\Help::class, [R::GET]],
@ -511,7 +519,7 @@ return [
'/newmember' => [Module\Welcome::class, [R::GET]],
'/nodeinfo/1.0' => [Module\NodeInfo110::class, [R::GET]],
'/nodeinfo/2.0' => [Module\NodeInfo120::class, [R::GET]],
'/nogroup' => [Module\Group::class, [R::GET]],
'/nocircle' => [Module\Circle::class, [R::GET]],
'/noscrape' => [
'/{nick}' => [Module\NoScrape::class, [R::GET]],
@ -660,7 +668,7 @@ return [
'[/]' => [Module\Conversation\Network::class, [R::GET]],
'/archive/{from:\d\d\d\d-\d\d-\d\d}[/{to:\d\d\d\d-\d\d-\d\d}]' => [Module\Conversation\Network::class, [R::GET]],
'/forum/{contact_id:\d+}' => [Module\Conversation\Network::class, [R::GET]],
'/group/{group_id:\d+}' => [Module\Conversation\Network::class, [R::GET]],
'/circle/{circle_id:\d+}' => [Module\Conversation\Network::class, [R::GET]],
],
'/randprof' => [Module\RandomProfile::class, [R::GET]],
@ -680,7 +688,7 @@ return [
'[/]' => [Module\Update\Network::class, [R::GET]],
'/archive/{from:\d\d\d\d-\d\d-\d\d}[/{to:\d\d\d\d-\d\d-\d\d}]' => [Module\Update\Network::class, [R::GET]],
'/forum/{contact_id:\d+}' => [Module\Update\Network::class, [R::GET]],
'/group/{group_id:\d+}' => [Module\Update\Network::class, [R::GET]],
'/circle/{circle_id:\d+}' => [Module\Update\Network::class, [R::GET]],
],
'/update_profile' => [Module\Update\Profile::class, [R::GET]],

View file

@ -114,9 +114,9 @@ return [
// Default value comprises classic role names from RFC 2142.
'forbidden_nicknames' => 'info, marketing, sales, support, abuse, noc, security, postmaster, hostmaster, usenet, news, webmaster, www, uucp, ftp, root, sysop',
// compute_group_counts (Boolean)
// Compute contact group level when counting unseen network posts.
'compute_group_counts' => true,
// compute_circle_counts (Boolean)
// Compute contact circle level when counting unseen network posts.
'compute_circle_counts' => true,
// jpeg_quality (Integer)
// Sets the ImageMagick quality level for JPEG images. Values ranges from 50 (awful) to 100 (near perfect).

View file

@ -21,7 +21,7 @@
namespace Friendica\Test\src\Util;
use Friendica\Model\Group;
use Friendica\Model\Circle;
use Friendica\Util\ACLFormatter;
use PHPUnit\Framework\TestCase;
@ -56,8 +56,8 @@ class ACLFormatterTest extends TestCase
{
return [
'normal' => [
'input' => '<1><2><3><' . Group::FOLLOWERS . '><' . Group::MUTUALS . '>',
'assert' => ['1', '2', '3', Group::FOLLOWERS, Group::MUTUALS],
'input' => '<1><2><3><' . Circle::FOLLOWERS . '><' . Circle::MUTUALS . '>',
'assert' => ['1', '2', '3', Circle::FOLLOWERS, Circle::MUTUALS],
],
'nigNumber' => [
'input' => '<1><' . PHP_INT_MAX . '><15>',
@ -128,12 +128,12 @@ class ACLFormatterTest extends TestCase
$aclFormatter = new ACLFormatter();
$allow_people = $aclFormatter->expand();
$allow_groups = $aclFormatter->expand();
$allow_circles = $aclFormatter->expand();
self::assertEmpty($aclFormatter->expand(null));
self::assertEmpty($aclFormatter->expand());
$recipients = array_unique(array_merge($allow_people, $allow_groups));
$recipients = array_unique(array_merge($allow_people, $allow_circles));
self::assertEmpty($recipients);
}
@ -165,13 +165,13 @@ class ACLFormatterTest extends TestCase
'input' => ["<40195>"],
'assert' => "<40195>",
],
Group::FOLLOWERS => [
'input' => [Group::FOLLOWERS, 1],
'assert' => '<' . Group::FOLLOWERS . '><1>',
Circle::FOLLOWERS => [
'input' => [Circle::FOLLOWERS, 1],
'assert' => '<' . Circle::FOLLOWERS . '><1>',
],
Group::MUTUALS => [
'input' => [Group::MUTUALS, 1],
'assert' => '<' . Group::MUTUALS . '><1>',
Circle::MUTUALS => [
'input' => [Circle::MUTUALS, 1],
'assert' => '<' . Circle::MUTUALS . '><1>',
],
'wrong-angle-brackets' => [
'input' => ["<asd>","<123>"],

View file

@ -24,7 +24,7 @@ function contact_search(term, callback, backend_url, type, mode) {
for(var t in contact_search.cache[bt]) {
if(lterm.indexOf(t) >= 0) { // A more broad search has been performed already, so use those results
// Filter old results locally
var matching = contact_search.cache[bt][t].filter(function (x) { return (x.name.toLowerCase().indexOf(lterm) >= 0 || (typeof x.nick !== 'undefined' && x.nick.toLowerCase().indexOf(lterm) >= 0)); }); // Need to check that nick exists because groups don't have one
var matching = contact_search.cache[bt][t].filter(function (x) { return (x.name.toLowerCase().indexOf(lterm) >= 0 || (typeof x.nick !== 'undefined' && x.nick.toLowerCase().indexOf(lterm) >= 0)); }); // Need to check that nick exists because circles don't have one
matching.unshift({forum:false, text: term, replace: term});
setTimeout(function() { callback(matching); } , 1); // Use "pseudo-thread" to avoid some problems
return;

View file

@ -289,11 +289,11 @@ $(function() {
$('#mail-update-li').html(mail);
$(".sidebar-group-li .notify").removeClass("show");
$(data.groups).each(function(key, group) {
var gid = group.id;
var gcount = group.count;
$(".group-"+gid+" .notify").addClass("show").text(gcount);
$(".sidebar-circle-li .notify").removeClass("show");
$(data.circles).each(function(key, circle) {
var gid = circle.id;
var gcount = circle.count;
$(".circle-"+gid+" .notify").addClass("show").text(gcount);
});
$(".forum-widget-entry .notify").removeClass("show");
@ -946,21 +946,21 @@ function bin2hex(s) {
return a.join('');
}
function groupChangeMember(gid, cid, sec_token) {
function circleChangeMember(gid, cid, sec_token) {
$('body .fakelink').css('cursor', 'wait');
$.get('group/' + gid + '/' + cid + "?t=" + sec_token, function(data) {
$('#group-update-wrapper').html(data);
$.get('circle/' + gid + '/' + cid + "?t=" + sec_token, function(data) {
$('#circle-update-wrapper').html(data);
$('body .fakelink').css('cursor', 'auto');
});
}
function contactgroupChangeMember(checkbox, gid, cid) {
function contactCircleChangeMember(checkbox, gid, cid) {
let url;
// checkbox.checked is the checkbox state after the click
if (checkbox.checked) {
url = 'group/' + gid + '/add/' + cid;
url = 'circle/' + gid + '/add/' + cid;
} else {
url = 'group/' + gid + '/remove/' + cid;
url = 'circle/' + gid + '/remove/' + cid;
}
$('body').css('cursor', 'wait');
$.post(url)

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2023.09-dev\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-05-26 07:34+0000\n"
"POT-Creation-Date: 2023-05-27 17:32-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -50,14 +50,14 @@ msgstr ""
#: src/Module/BaseNotifications.php:98 src/Module/BaseSettings.php:52
#: src/Module/Calendar/Event/API.php:88 src/Module/Calendar/Event/Form.php:84
#: src/Module/Calendar/Export.php:82 src/Module/Calendar/Show.php:82
#: src/Module/Circle.php:40 src/Module/Circle.php:83
#: src/Module/Contact/Advanced.php:60 src/Module/Contact/Follow.php:87
#: src/Module/Contact/Follow.php:160 src/Module/Contact/MatchInterests.php:86
#: src/Module/Contact/Suggestions.php:54 src/Module/Contact/Unfollow.php:66
#: src/Module/Contact/Unfollow.php:80 src/Module/Contact/Unfollow.php:112
#: src/Module/Delegation.php:118 src/Module/FollowConfirm.php:38
#: src/Module/FriendSuggest.php:57 src/Module/Group.php:40
#: src/Module/Group.php:83 src/Module/Invite.php:42 src/Module/Invite.php:131
#: src/Module/Notifications/Notification.php:76
#: src/Module/FriendSuggest.php:57 src/Module/Invite.php:42
#: src/Module/Invite.php:131 src/Module/Notifications/Notification.php:76
#: src/Module/Notifications/Notification.php:107
#: src/Module/OStatus/Repair.php:60 src/Module/OStatus/Subscribe.php:66
#: src/Module/Post/Edit.php:76 src/Module/Profile/Common.php:75
@ -2017,39 +2017,39 @@ msgstr ""
msgid "last"
msgstr ""
#: src/Content/Text/BBCode.php:713 src/Content/Text/BBCode.php:1619
#: src/Content/Text/BBCode.php:1620
#: src/Content/Text/BBCode.php:694 src/Content/Text/BBCode.php:1600
#: src/Content/Text/BBCode.php:1601
msgid "Image/photo"
msgstr ""
#: src/Content/Text/BBCode.php:931
#: src/Content/Text/BBCode.php:912
#, php-format
msgid ""
"<a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">%2$s</a> %3$s"
msgstr ""
#: src/Content/Text/BBCode.php:956 src/Model/Item.php:3649
#: src/Content/Text/BBCode.php:937 src/Model/Item.php:3649
#: src/Model/Item.php:3655 src/Model/Item.php:3656
msgid "Link to source"
msgstr ""
#: src/Content/Text/BBCode.php:1526 src/Content/Text/HTML.php:901
#: src/Content/Text/BBCode.php:1507 src/Content/Text/HTML.php:901
msgid "Click to open/close"
msgstr ""
#: src/Content/Text/BBCode.php:1559
#: src/Content/Text/BBCode.php:1540
msgid "$1 wrote:"
msgstr ""
#: src/Content/Text/BBCode.php:1624 src/Content/Text/BBCode.php:1625
#: src/Content/Text/BBCode.php:1605 src/Content/Text/BBCode.php:1606
msgid "Encrypted content"
msgstr ""
#: src/Content/Text/BBCode.php:1889
#: src/Content/Text/BBCode.php:1870
msgid "Invalid source protocol"
msgstr ""
#: src/Content/Text/BBCode.php:1908
#: src/Content/Text/BBCode.php:1889
msgid "Invalid link protocol"
msgstr ""
@ -2132,9 +2132,9 @@ msgstr ""
msgid "Local Directory"
msgstr ""
#: src/Content/Widget.php:219 src/Model/Group.php:596
#: src/Content/Widget.php:219 src/Model/Circle.php:596
#: src/Module/Contact.php:394 src/Module/Welcome.php:76
msgid "Groups"
msgid "Circles"
msgstr ""
#: src/Content/Widget.php:221
@ -2145,8 +2145,8 @@ msgstr ""
msgid "Relationships"
msgstr ""
#: src/Content/Widget.php:252 src/Module/Contact.php:338
#: src/Module/Group.php:291
#: src/Content/Widget.php:252 src/Module/Circle.php:293
#: src/Module/Contact.php:338
msgid "All Contacts"
msgstr ""
@ -2313,8 +2313,8 @@ msgstr ""
#: src/Core/ACL.php:324
msgid ""
"Start typing the name of a contact or a group to show a filtered list. You "
"can also mention the special groups \"Followers\" and \"Mutuals\"."
"Start typing the name of a contact or a circle to show a filtered list. You "
"can also mention the special circles \"Followers\" and \"Mutuals\"."
msgstr ""
#: src/Core/ACL.php:325
@ -2974,6 +2974,50 @@ msgstr ""
msgid "Legacy module file not found: %s"
msgstr ""
#: src/Model/Circle.php:105
msgid ""
"A deleted circle with this name was revived. Existing item permissions "
"<strong>may</strong> apply to this circle and any future members. If this is "
"not what you intended, please create another circle with a different name."
msgstr ""
#: src/Model/Circle.php:512
msgid "Default privacy circle for new contacts"
msgstr ""
#: src/Model/Circle.php:544
msgid "Everybody"
msgstr ""
#: src/Model/Circle.php:563
msgid "edit"
msgstr ""
#: src/Model/Circle.php:595
msgid "add"
msgstr ""
#: src/Model/Circle.php:600
msgid "Edit circle"
msgstr ""
#: src/Model/Circle.php:601 src/Module/Circle.php:194
msgid "Contacts not in any circle"
msgstr ""
#: src/Model/Circle.php:603
msgid "Create a new circle"
msgstr ""
#: src/Model/Circle.php:604 src/Module/Circle.php:179 src/Module/Circle.php:202
#: src/Module/Circle.php:277
msgid "Circle Name: "
msgstr ""
#: src/Model/Circle.php:605
msgid "Edit circles"
msgstr ""
#: src/Model/Contact.php:1212 src/Module/Moderation/Users/Pending.php:102
#: src/Module/Notifications/Introductions.php:132
#: src/Module/Notifications/Introductions.php:204
@ -3154,50 +3198,6 @@ msgstr ""
msgid "Happy Birthday %s"
msgstr ""
#: src/Model/Group.php:105
msgid ""
"A deleted group with this name was revived. Existing item permissions "
"<strong>may</strong> apply to this group and any future members. If this is "
"not what you intended, please create another group with a different name."
msgstr ""
#: src/Model/Group.php:512
msgid "Default privacy group for new contacts"
msgstr ""
#: src/Model/Group.php:544
msgid "Everybody"
msgstr ""
#: src/Model/Group.php:563
msgid "edit"
msgstr ""
#: src/Model/Group.php:595
msgid "add"
msgstr ""
#: src/Model/Group.php:600
msgid "Edit group"
msgstr ""
#: src/Model/Group.php:601 src/Module/Group.php:192
msgid "Contacts not in any group"
msgstr ""
#: src/Model/Group.php:603
msgid "Create a new group"
msgstr ""
#: src/Model/Group.php:604 src/Module/Group.php:177 src/Module/Group.php:200
#: src/Module/Group.php:275
msgid "Group Name: "
msgstr ""
#: src/Model/Group.php:605
msgid "Edit groups"
msgstr ""
#: src/Model/Item.php:2023
#, php-format
msgid "Detected languages in this post:\\n%s"
@ -3560,7 +3560,7 @@ msgstr ""
#: src/Model/User.php:1197
msgid ""
"An error occurred creating your default contact group. Please try again."
"An error occurred creating your default contact circle. Please try again."
msgstr ""
#: src/Model/User.php:1236
@ -4543,7 +4543,7 @@ msgstr ""
#: src/Module/Admin/Site.php:455
msgid ""
"Set default post permissions for all new members to the default privacy "
"group rather than public."
"circle rather than public."
msgstr ""
#: src/Module/Admin/Site.php:456
@ -4957,12 +4957,12 @@ msgid "On large systems the text search can slow down the system extremely."
msgstr ""
#: src/Module/Admin/Site.php:507
msgid "Generate counts per contact group when calculating network count"
msgid "Generate counts per contact circle when calculating network count"
msgstr ""
#: src/Module/Admin/Site.php:507
msgid ""
"On systems with users that heavily use contact groups the query can be very "
"On systems with users that heavily use contact circles the query can be very "
"expensive."
msgstr ""
@ -5724,6 +5724,108 @@ msgstr ""
msgid "list"
msgstr ""
#: src/Module/Circle.php:56
msgid "Could not create circle."
msgstr ""
#: src/Module/Circle.php:67 src/Module/Circle.php:215 src/Module/Circle.php:239
msgid "Circle not found."
msgstr ""
#: src/Module/Circle.php:73
msgid "Circle name was not changed."
msgstr ""
#: src/Module/Circle.php:91
msgid "Unknown circle."
msgstr ""
#: src/Module/Circle.php:97 src/Module/Circle.php:106
#: src/Module/Contact/Advanced.php:70 src/Module/Contact/Advanced.php:109
#: src/Module/Contact/Contacts.php:71 src/Module/Contact/Conversations.php:84
#: src/Module/Contact/Conversations.php:89
#: src/Module/Contact/Conversations.php:94 src/Module/Contact/Media.php:43
#: src/Module/Contact/Posts.php:78 src/Module/Contact/Posts.php:83
#: src/Module/Contact/Posts.php:88 src/Module/Contact/Profile.php:142
#: src/Module/Contact/Profile.php:147 src/Module/Contact/Profile.php:152
#: src/Module/Contact/Redir.php:94 src/Module/Contact/Redir.php:140
#: src/Module/FriendSuggest.php:71 src/Module/FriendSuggest.php:109
msgid "Contact not found."
msgstr ""
#: src/Module/Circle.php:101 src/Module/Contact/Contacts.php:66
#: src/Module/Conversation/Network.php:189
msgid "Invalid contact."
msgstr ""
#: src/Module/Circle.php:110 src/Module/Contact/Revoke.php:73
msgid "Contact is deleted."
msgstr ""
#: src/Module/Circle.php:116
msgid "Unable to add the contact to the circle."
msgstr ""
#: src/Module/Circle.php:119
msgid "Contact successfully added to circle."
msgstr ""
#: src/Module/Circle.php:123
msgid "Unable to remove the contact from the circle."
msgstr ""
#: src/Module/Circle.php:126
msgid "Contact successfully removed from circle."
msgstr ""
#: src/Module/Circle.php:130
msgid "Bad request."
msgstr ""
#: src/Module/Circle.php:171
msgid "Save Circle"
msgstr ""
#: src/Module/Circle.php:172
msgid "Filter"
msgstr ""
#: src/Module/Circle.php:178
msgid "Create a circle of contacts/friends."
msgstr ""
#: src/Module/Circle.php:220
msgid "Unable to remove circle."
msgstr ""
#: src/Module/Circle.php:271
msgid "Delete Circle"
msgstr ""
#: src/Module/Circle.php:281
msgid "Edit Circle Name"
msgstr ""
#: src/Module/Circle.php:291
msgid "Members"
msgstr ""
#: src/Module/Circle.php:294
msgid "Circle is empty"
msgstr ""
#: src/Module/Circle.php:307
msgid "Remove contact from circle"
msgstr ""
#: src/Module/Circle.php:328
msgid "Click on a contact to add or remove."
msgstr ""
#: src/Module/Circle.php:342
msgid "Add contact to circle"
msgstr ""
#: src/Module/Contact.php:97
#, php-format
msgid "%d contact edited."
@ -5787,7 +5889,7 @@ msgid "Only show hidden contacts"
msgstr ""
#: src/Module/Contact.php:397
msgid "Organize your contact groups"
msgid "Organize your contact circles"
msgstr ""
#: src/Module/Contact.php:430
@ -5871,19 +5973,6 @@ msgstr ""
msgid "Visit %s's profile [%s]"
msgstr ""
#: src/Module/Contact/Advanced.php:70 src/Module/Contact/Advanced.php:109
#: src/Module/Contact/Contacts.php:71 src/Module/Contact/Conversations.php:84
#: src/Module/Contact/Conversations.php:89
#: src/Module/Contact/Conversations.php:94 src/Module/Contact/Media.php:43
#: src/Module/Contact/Posts.php:78 src/Module/Contact/Posts.php:83
#: src/Module/Contact/Posts.php:88 src/Module/Contact/Profile.php:142
#: src/Module/Contact/Profile.php:147 src/Module/Contact/Profile.php:152
#: src/Module/Contact/Redir.php:94 src/Module/Contact/Redir.php:140
#: src/Module/FriendSuggest.php:71 src/Module/FriendSuggest.php:109
#: src/Module/Group.php:97 src/Module/Group.php:106
msgid "Contact not found."
msgstr ""
#: src/Module/Contact/Advanced.php:99
msgid "Contact update failed."
msgstr ""
@ -5920,11 +6009,6 @@ msgstr ""
msgid "New photo from this URL"
msgstr ""
#: src/Module/Contact/Contacts.php:66 src/Module/Conversation/Network.php:189
#: src/Module/Group.php:101
msgid "Invalid contact."
msgstr ""
#: src/Module/Contact/Contacts.php:89
msgid "No known contacts."
msgstr ""
@ -6319,10 +6403,6 @@ msgstr ""
msgid "Unknown contact."
msgstr ""
#: src/Module/Contact/Revoke.php:73 src/Module/Group.php:110
msgid "Contact is deleted."
msgstr ""
#: src/Module/Contact/Revoke.php:77
msgid "Contact is being deleted."
msgstr ""
@ -6418,12 +6498,12 @@ msgid "Not available."
msgstr ""
#: src/Module/Conversation/Network.php:175
msgid "No such group"
msgid "No such circle"
msgstr ""
#: src/Module/Conversation/Network.php:179
#, php-format
msgid "Group: %s"
msgid "Circle: %s"
msgstr ""
#: src/Module/Conversation/Network.php:257
@ -6865,86 +6945,6 @@ msgid ""
"Suggestions, praise, etc. - please email \"info\" at \"friendi - dot - ca"
msgstr ""
#: src/Module/Group.php:56
msgid "Could not create group."
msgstr ""
#: src/Module/Group.php:67 src/Module/Group.php:213 src/Module/Group.php:237
msgid "Group not found."
msgstr ""
#: src/Module/Group.php:73
msgid "Group name was not changed."
msgstr ""
#: src/Module/Group.php:91
msgid "Unknown group."
msgstr ""
#: src/Module/Group.php:116
msgid "Unable to add the contact to the group."
msgstr ""
#: src/Module/Group.php:119
msgid "Contact successfully added to group."
msgstr ""
#: src/Module/Group.php:123
msgid "Unable to remove the contact from the group."
msgstr ""
#: src/Module/Group.php:126
msgid "Contact successfully removed from group."
msgstr ""
#: src/Module/Group.php:130
msgid "Bad request."
msgstr ""
#: src/Module/Group.php:169
msgid "Save Group"
msgstr ""
#: src/Module/Group.php:170
msgid "Filter"
msgstr ""
#: src/Module/Group.php:176
msgid "Create a group of contacts/friends."
msgstr ""
#: src/Module/Group.php:218
msgid "Unable to remove group."
msgstr ""
#: src/Module/Group.php:269
msgid "Delete Group"
msgstr ""
#: src/Module/Group.php:279
msgid "Edit Group Name"
msgstr ""
#: src/Module/Group.php:289
msgid "Members"
msgstr ""
#: src/Module/Group.php:292
msgid "Group is empty"
msgstr ""
#: src/Module/Group.php:305
msgid "Remove contact from group"
msgstr ""
#: src/Module/Group.php:326
msgid "Click on a contact to add or remove."
msgstr ""
#: src/Module/Group.php:340
msgid "Add contact to group"
msgstr ""
#: src/Module/HCard.php:45
msgid "No profile"
msgstr ""
@ -8350,20 +8350,20 @@ msgstr ""
#: src/Module/Profile/Conversations.php:106
#: src/Module/Profile/Conversations.php:109 src/Module/Profile/Profile.php:351
#: src/Module/Profile/Profile.php:354 src/Protocol/Feed.php:1092
#: src/Module/Profile/Profile.php:354 src/Protocol/Feed.php:1090
#: src/Protocol/OStatus.php:1007
#, php-format
msgid "%s's timeline"
msgstr ""
#: src/Module/Profile/Conversations.php:107 src/Module/Profile/Profile.php:352
#: src/Protocol/Feed.php:1096 src/Protocol/OStatus.php:1012
#: src/Protocol/Feed.php:1094 src/Protocol/OStatus.php:1012
#, php-format
msgid "%s's posts"
msgstr ""
#: src/Module/Profile/Conversations.php:108 src/Module/Profile/Profile.php:353
#: src/Protocol/Feed.php:1099 src/Protocol/OStatus.php:1016
#: src/Protocol/Feed.php:1097 src/Protocol/OStatus.php:1016
#, php-format
msgid "%s's comments"
msgstr ""
@ -10029,7 +10029,7 @@ msgid ""
"\t\t\t\t<p>Reorder by dragging the field title.</p>\n"
"\t\t\t\t<p>Empty the label field to remove a custom field.</p>\n"
"\t\t\t\t<p>Non-public fields can only be seen by the selected Friendica "
"contacts or the Friendica contacts in the selected groups.</p>"
"contacts or the Friendica contacts in the selected circles.</p>"
msgstr ""
#: src/Module/Settings/Profile/Photo/Crop.php:107
@ -10580,22 +10580,22 @@ msgstr ""
msgid "User '%s' already exists on this server!"
msgstr ""
#: src/Module/User/Import.php:263
#: src/Module/User/Import.php:267
msgid "User creation error"
msgstr ""
#: src/Module/User/Import.php:312
#: src/Module/User/Import.php:316
#, php-format
msgid "%d contact not imported"
msgid_plural "%d contacts not imported"
msgstr[0] ""
msgstr[1] ""
#: src/Module/User/Import.php:361
#: src/Module/User/Import.php:365
msgid "User profile creation error"
msgstr ""
#: src/Module/User/Import.php:412
#: src/Module/User/Import.php:416
msgid "Done. You can now login with your username and password"
msgstr ""
@ -10729,14 +10729,14 @@ msgid ""
msgstr ""
#: src/Module/Welcome.php:77
msgid "Group Your Contacts"
msgid "Add Your Contacts To Circle"
msgstr ""
#: src/Module/Welcome.php:78
msgid ""
"Once you have made some friends, organize them into private conversation "
"groups from the sidebar of your Contacts page and then you can interact with "
"each group privately on your Network page."
"circles from the sidebar of your Contacts page and then you can interact "
"with each circle privately on your Network page."
msgstr ""
#: src/Module/Welcome.php:80

View file

@ -41,9 +41,9 @@
<i class="fa fa-lock"></i> {{$custom_title}}
</label>
<fieldset id="visibility-custom-panel-{{$input_group_id}}" class="panel-collapse collapse{{if $visibility == 'custom'}} in{{/if}}" role="tabpanel" aria-labelledby="visibility-custom-heading-{{$input_group_id}}" {{if $visibility != 'custom'}}disabled{{/if}}>
<input type="hidden" name="{{$input_names.group_allow}}" value="{{$group_allow}}"/>
<input type="hidden" name="{{$input_names.circle_allow}}" value="{{$circle_allow}}"/>
<input type="hidden" name="{{$input_names.contact_allow}}" value="{{$contact_allow}}"/>
<input type="hidden" name="{{$input_names.group_deny}}" value="{{$group_deny}}"/>
<input type="hidden" name="{{$input_names.circle_deny}}" value="{{$circle_deny}}"/>
<input type="hidden" name="{{$input_names.contact_deny}}" value="{{$contact_deny}}"/>
<div class="panel-body">
<p>{{$custom_desc}}</p>
@ -75,10 +75,10 @@
$(function() {
let $acl_allow_input = $('#acl_allow-{{$input_group_id}}');
let $contact_allow_input = $('[name="{{$input_names.contact_allow}}"]');
let $group_allow_input = $('[name="{{$input_names.group_allow}}"]');
let $circle_allow_input = $('[name="{{$input_names.circle_allow}}"]');
let $acl_deny_input = $('#acl_deny-{{$input_group_id}}');
let $contact_deny_input = $('[name="{{$input_names.contact_deny}}"]');
let $group_deny_input = $('[name="{{$input_names.group_deny}}"]');
let $circle_deny_input = $('[name="{{$input_names.circle_deny}}"]');
let $visibility_public_panel = $('#visibility-public-panel-{{$input_group_id}}');
let $visibility_custom_panel = $('#visibility-custom-panel-{{$input_group_id}}');
let $visibility_public_radio = $('#visibility-public-{{$input_group_id}}');
@ -125,8 +125,8 @@
});
// Custom visibility tags inputs
let acl_groups = new Bloodhound({
local: {{$acl_groups nofilter}},
let acl_circles = new Bloodhound({
local: {{$acl_circles nofilter}},
identify: function(obj) { return obj.type + '-' + obj.id.toString(); },
datumTokenizer: Bloodhound.tokenizers.obj.whitespace(['name']),
queryTokenizer: Bloodhound.tokenizers.whitespace,
@ -163,7 +163,7 @@
freeInput: false,
tagClass: function(item) {
switch (item.type) {
case 'group' : return 'label label-primary';
case 'circle' : return 'label label-primary';
case 'contact' :
default:
return 'label label-info';
@ -191,7 +191,7 @@
freeInput: false,
tagClass: function(item) {
switch (item.type) {
case 'group' : return 'label label-primary';
case 'circle' : return 'label label-primary';
case 'contact' :
default:
return 'label label-info';
@ -215,14 +215,14 @@
// Import existing ACL into the tags input fields.
$group_allow_input.val().split(',').forEach(function (group_id) {
$acl_allow_input.tagsinput('add', acl_groups.get('group-' + group_id)[0]);
$circle_allow_input.val().split(',').forEach(function (circle_id) {
$acl_allow_input.tagsinput('add', acl_circles.get('circle-' + circle_id)[0]);
});
$contact_allow_input.val().split(',').forEach(function (contact_id) {
$acl_allow_input.tagsinput('add', acl_contacts.get('contact-' + contact_id)[0]);
});
$group_deny_input.val().split(',').forEach(function (group_id) {
$acl_deny_input.tagsinput('add', acl_groups.get('group-' + group_id)[0]);
$circle_deny_input.val().split(',').forEach(function (circle_id) {
$acl_deny_input.tagsinput('add', acl_circles.get('circle-' + circle_id)[0]);
});
$contact_deny_input.val().split(',').forEach(function (contact_id) {
$acl_deny_input.tagsinput('add', acl_contacts.get('contact-' + contact_id)[0]);
@ -237,11 +237,11 @@
}
// Update the real acl field
$group_allow_input.val('');
$circle_allow_input.val('');
$contact_allow_input.val('');
[].forEach.call($acl_allow_input.tagsinput('items'), function (item) {
if (item.type === 'group') {
$group_allow_input.val($group_allow_input.val() + ',' + item.id);
if (item.type === 'circle') {
$circle_allow_input.val($circle_allow_input.val() + ',' + item.id);
} else {
$contact_allow_input.val($contact_allow_input.val() + ',' + item.id);
}
@ -255,11 +255,11 @@
}
// Update the real acl field
$group_deny_input.val('');
$circle_deny_input.val('');
$contact_deny_input.val('');
[].forEach.call($acl_deny_input.tagsinput('items'), function (item) {
if (item.type === 'group') {
$group_deny_input.val($group_deny_input.val() + ',' + item.id);
if (item.type === 'circle') {
$circle_deny_input.val($circle_deny_input.val() + ',' + item.id);
} else {
$contact_deny_input.val($contact_deny_input.val() + ',' + item.id);
}

View file

@ -1,5 +1,5 @@
<input type="hidden" name="contact_allow" value="{{$selfPublicContactId}}">
<input type="hidden" name="group_allow" value="">
<input type="hidden" name="circle_allow" value="">
<input type="hidden" name="contact_deny" value="">
<input type="hidden" name="group_deny" value="">
<input type="hidden" name="circle_deny" value="">
<div class="alert alert-info" role="alert"><p>{{$explanation}}</p></div>

View file

@ -108,7 +108,7 @@
<div class="submit"><input type="submit" name="page_site" value="{{$submit}}"/></div>
<h2>{{$performance}}</h2>
{{include file="field_checkbox.tpl" field=$compute_group_counts}}
{{include file="field_checkbox.tpl" field=$compute_circle_counts}}
{{include file="field_checkbox.tpl" field=$only_tag_search}}
{{include file="field_input.tpl" field=$max_comments}}
{{include file="field_input.tpl" field=$max_display_comments}}

Some files were not shown because too many files have changed in this diff Show more