1 <?php
2
3 /*
4 * This file is part of the Icybee package.
5 *
6 * (c) Olivier Laviale <olivier.laviale@gmail.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Icybee\Modules\Users;
13
14 use ICanBoogie\ActiveRecord;
15
16 class OwnershipResolver implements \ArrayAccess, \IteratorAggregate, OwnershipResolverInterface
17 {
18 /**
19 * Synthesizes the `users_ownership_resolver_list` config from `users` fragments.
20 *
21 * @param array $fragments
22 *
23 * @return array
24 */
25 static public function synthesize_config(array $fragments)
26 {
27 $list = [];
28 $weight = [];
29
30 foreach ($fragments as $fragment)
31 {
32 if (empty($fragment['ownership_resolver_list']))
33 {
34 continue;
35 }
36
37 foreach ($fragment['ownership_resolver_list'] as $resolver_id => $resolver)
38 {
39 $resolver = ((array) $resolver) + [ 'weight' => 0 ];
40
41 $list[$resolver_id] = $resolver[0];
42 $weight[$resolver_id] = $resolver['weight'];
43 }
44 }
45
46 return \ICanBoogie\sort_by_weight($list, function($v, $k) use($weight) {
47
48 return $weight[$k];
49
50 });
51 }
52
53 private $list = [];
54
55 /**
56 * Initializes the ownership resolver list.
57 *
58 * @param array $resolver_list A ownership resolver list, such as one created by
59 * {@link autoconfig()}.
60 */
61 public function __construct(array $resolver_list=[])
62 {
63 foreach ($resolver_list as $resolver_id => $resolver)
64 {
65 $this[$resolver_id] = $resolver;
66 }
67 }
68
69 public function __invoke(User $user, ActiveRecord $record)
70 {
71 $granted = false;
72
73 foreach ($this->list as $resolver_id => &$resolver)
74 {
75 if (!is_callable($resolver))
76 {
77 $resolver = new $resolver;
78 }
79
80 $resolver_grant = call_user_func($resolver, $user, $record);
81
82 if ($resolver_grant === null)
83 {
84 continue;
85 }
86
87 $granted = $resolver_grant;
88 }
89
90 return $granted;
91 }
92
93 public function getIterator()
94 {
95 return new \ArrayIterator($this->list);
96 }
97
98 public function offsetExists($resolver_id)
99 {
100 return isset($this->list[$resolver_id]);
101 }
102
103 public function offsetGet($resolver_id)
104 {
105 return $this->list[$resolver_id];
106 }
107
108 public function offsetSet($resolver_id, $resolver)
109 {
110 $this->list[$resolver_id] = $resolver;
111 }
112
113 public function offsetUnset($resolver_id)
114 {
115 unset($this->list[$resolver_id]);
116 }
117 }
118
119 interface OwnershipResolverInterface
120 {
121 /**
122 * Resolves the owneship of a user.
123 *
124 * @param User $user A user record.
125 * @param ActiveRecord $record A record.
126 *
127 * @return boolean `true` if the user has the ownership of the record.
128 */
129 public function __invoke(User $user, ActiveRecord $record);
130 }