ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
RelationsTable.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
29 use ilCtrlInterface;
33 use ilObjUser;
34 use ilStr;
35 use ilUserUtil;
36 use ilBuddyList;
39 use ilLanguage;
41 use ilUIService;
43 use Closure;
45 use Generator;
46 
48 {
49  public function __construct(
50  private readonly UIFactory $create,
51  private readonly ilLanguage $lng,
52  private readonly ilUIService $ui_service,
53  private readonly Http $http
54  ) {
55  }
56 
61  public static function data(array $filter = []): array
62  {
63  $relations = ilBuddyList::getInstanceByGlobalUser()->getRelations();
64 
65  $state_filter = (string) ($filter['state'] ?? '');
67 
68  if ($state_filter) {
69  $relations = $relations->filter(static fn(ilBuddySystemRelation $relation): bool => (
70  $state_factory
71  ->getTableFilterStateMapper($relation->getState())
72  ->filterMatchesRelation($state_filter, $relation)
73  ));
74  }
75 
76  $public_names = ilUserUtil::getNamePresentation($relations->getKeys(), false, false, '', false, true, false);
78  $logins = ilUserUtil::getNamePresentation($relations->getKeys(), false, false, '', false, false, false);
79 
80  $logins = array_map(static function (string $value): string {
81  $matches = null;
82  preg_match_all('/\[([^\[]+?)\]/', $value, $matches);
83  return $matches[1][count($matches[1]) - 1] ?? '';
84  }, $logins);
85 
86  $public_name_query = (string) ($filter['name'] ?? '');
87  if ($public_name_query) {
88  $relations = $relations->filter(self::filter($public_name_query, $relations, $public_names, $logins));
89  }
90 
91  $data = [];
92  foreach ($relations->toArray() as $user_id => $relation) {
93  $txt = $state_factory->getTableFilterStateMapper($relation->getState())->text($relation);
94  $data[] = [
95  'user_id' => $user_id,
96  'public_name' => $public_names[$user_id],
97  'login' => $logins[$user_id],
98  'state' => $relation->getState(),
99  'points' => $relation->getCurrentPossibleTargetStates()->toArray(),
100  'state-text' => $txt,
101  ];
102  }
103 
104  return $data;
105  }
106 
112  public function build(array $multi_actions, string $target_url, callable $action): array
113  {
114  $filter = $this->filterComponent($target_url);
115  $data = static::data($this->ui_service->filter()->getData($filter) ?: []);
116  $single_actions = $this->actions($data, $action);
117 
118  $rows = $this->rows($data, array_keys($single_actions));
119  $return = [];
120  $return[] = $filter;
121  $return[] = $this->create->table()->data(
122  new TableRows($rows),
123  $this->lng->txt('buddy_tbl_title_relations'),
124  [
125  'public_name' => $this->create->table()->column()->text($this->lng->txt('name')),
126  'login' => $this->create->table()->column()->text($this->lng->txt('login')),
127  'state-text' => $this->create->table()->column()
128  ->text($this->lng->txt('buddy_tbl_state_actions_col_label')),
129  ]
130  )->withRequest($this->http->request())->withActions(
131  array_merge($single_actions, $multi_actions)
132  );
133 
134  return $return;
135  }
136 
144  private static function filter(string $public_name_query, ilBuddySystemArrayCollection $relations, array $public_names, array $logins): Closure
145  {
146  $in_string = static fn(string $needle, string $haystack): bool => false !== ilStr::strpos(
147  ilStr::strtolower($haystack),
148  ilStr::strtolower($needle),
149  0
150  );
151 
152  return self::pipe($relations->getKey(...), static fn(int $user_id): bool => (
153  $in_string($public_name_query, $public_names[$user_id]) ||
154  $in_string($public_name_query, $logins[$user_id])
155  ) && ilObjUser::_lookupActive($user_id));
156  }
157 
158  private static function pipe(Closure $a, Closure $b): Closure
159  {
160  return static fn($x) => $b($a($x));
161  }
162 
169  private function actions(array $data, callable $action): array
170  {
171  $actions = [];
172  foreach ($data as $row) {
173  foreach ($row['points'] as $point) {
174  $actions[$row['state'] . '->' . $point] = $action(
175  'single',
176  'buddy_bs_act_btn_txt_' . $row['state']->getSnakeName() . '_to_' . $point->getSnakeName(),
177  $point->getAction()
178  );
179  }
180  }
181 
182  return $actions;
183  }
184 
185  private function filterComponent(string $target_url): Filter
186  {
188  $options = array_merge(...array_map(
189  fn($m): array => $m->optionsForState(),
190  array_map(
191  $state_factory->getTableFilterStateMapper(...),
192  array_filter($state_factory->getValidStates(), fn($s): bool => !$s->isInitial())
193  )
194  ));
195 
196  $fields = [
197  'state' => $this->create->input()->field()->select($this->lng->txt('buddy_tbl_filter_state'), $options),
198  'name' => $this->create->input()->field()->text($this->lng->txt('name')),
199  ];
200 
201  return $this->ui_service->filter()->standard(
202  'contact-filter',
203  $target_url,
204  $fields,
205  array_map(fn(): bool => true, $fields),
206  true,
207  true
208  );
209  }
210 
215  private function rows(array $data, array $actions): Closure
216  {
217  return static function (
218  DataRowBuilder $row_builder,
219  array $visible_column_ids,
220  Range $range,
221  Order $order
222  ) use ($data, $actions): Generator {
223  $order = $order->get();
224  $times = current($order) === 'ASC' ? 1 : -1;
225  usort($data, fn(array $a, array $b): int => $times * strcasecmp($a[key($order)], $b[key($order)]));
226  foreach ($data as $row) {
227  $transitions = array_map(fn($s): string => $row['state'] . '->' . $s, $row['points']);
228  yield array_reduce(
229  $actions,
230  fn(DataRow $row, string $action): DataRow => in_array($action, $transitions, true) ?
231  $row :
232  $row->withDisabledAction($action),
233  $row_builder->buildDataRow((string) $row['user_id'], $row)
234  );
235  }
236  };
237  }
238 }
withDisabledAction(string $action_id, bool $disable=true)
Refer to an Action by its id and disable it for this row/record only.
$relation
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$http
Definition: deliver.php:30
Both the subject and the direction need to be specified when expressing an order. ...
Definition: Order.php:28
buildDataRow(string $id, array $record)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static filter(string $public_name_query, ilBuddySystemArrayCollection $relations, array $public_names, array $logins)
A
static http()
Fetches the global http state from ILIAS.
static getNamePresentation( $a_user_id, bool $a_user_image=false, bool $a_profile_link=false, string $a_profile_back_link='', bool $a_force_first_lastname=false, bool $a_omit_login=false, bool $a_sortable=true, bool $a_return_data_array=false, $a_ctrl_path='ilpublicuserprofilegui')
Default behaviour is:
__construct(private readonly UIFactory $create, private readonly ilLanguage $lng, private readonly ilUIService $ui_service, private readonly Http $http)
$txt
Definition: error.php:31
global $lng
Definition: privfeed.php:31
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
filter(string $filter_id, $class_path, string $cmd, bool $activated=true, bool $expanded=true)
build(array $multi_actions, string $target_url, callable $action)
A simple class to express a naive range of whole positive numbers.
Definition: Range.php:28
static _lookupActive(int $a_usr_id)
static getInstanceByGlobalUser(?ilObjUser $user=null)