3 * @copyright Copyright (C) 2010-2024, the Friendica project
5 * @license GNU AGPL version 3 or any later version
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 namespace Friendica\Util;
24 use Friendica\Model\Circle;
27 * Util class for ACL formatting
29 final class ACLFormatter
32 * Turn user/circle ACLs stored as angle bracketed text into arrays
34 * @param string|null $acl_string A angle-bracketed list of IDs
36 * @return array The array based on the IDs (empty in case there is no list)
38 public function expand(string $acl_string = null): array
40 // In case there is no ID list, return empty array (=> no ACL set)
41 if (empty($acl_string)) {
45 // turn string array of angle-bracketed elements into numeric array
46 // e.g. "<1><2><3>" => array(1,2,3);
47 preg_match_all('/<(' . Circle::FOLLOWERS . '|'. Circle::MUTUALS . '|[0-9]+)>/', $acl_string, $matches, PREG_PATTERN_ORDER);
53 * Takes an arbitrary ACL string and sanitizes it for storage
55 * @param string|null $acl_string
58 public function sanitize(string $acl_string = null): string
60 if (empty($acl_string)) {
64 $cleaned_list = trim($acl_string, '<>');
66 if (empty($cleaned_list)) {
70 $elements = explode('><', $cleaned_list);
74 array_walk($elements, [$this, 'sanitizeItem']);
76 return implode('', $elements);
80 * Wrap ACL elements in angle brackets for storage
82 * @param string $item The item to sanitise
84 private function sanitizeItem(string &$item) {
85 // The item is an ACL int value
87 $item = '<' . intval($item) . '>';
88 // The item is a allowed ACL character
89 } elseif (in_array($item, [Circle::FOLLOWERS, Circle::MUTUALS])) {
90 $item = '<' . $item . '>';
91 // The item is already a ACL string
92 } elseif (preg_match('/<\d+?>/', $item)) {
94 // The item is not supported, so remove it (cleanup)
101 * Convert an ACL array to a storable string
103 * Normally ACL permissions will be an array.
104 * We'll also allow a comma-separated string.
106 * @param string|array $permissions
110 function toString($permissions): string
113 if (is_array($permissions)) {
114 $item = $permissions;
115 } elseif (empty($permissions)) {
118 $item = explode(',', $permissions);
121 if (is_array($item)) {
122 array_walk($item, [$this, 'sanitizeItem']);
123 $return = implode('', $item);