*/ class ForumPerms { private static $table = 'forum_perms'; private $forums = []; private $user = 0; private $ranks = []; private $permCache = []; private $validCache = []; public function __construct(Forum $forum, User $user) { $this->forums = iterator_to_array($this->getForumIds($forum->id)); $this->user = $user->id; $this->ranks = array_keys($user->ranks); } public function getForumIds(int $id): Traversable { // yield the initial id yield $id; while ($id > 0) { $id = DB::table('forums') ->where('forum_id', $id) ->value('forum_category'); yield $id; } } public function __get(string $name): bool { return $this->check($name); } public function __isset(string $name): bool { return $this->valid($name); } public function valid(string $name): bool { if (!array_key_exists($name, $this->validCache)) { $column = 'perm_' . camel_to_snake($name); $this->validCache[$name] = DB::getSchemaBuilder()->hasColumn(static::$table, $column); } return $this->validCache[$name]; } public function check(string $name): bool { if (!array_key_exists($name, $this->permCache)) { $column = 'perm_' . camel_to_snake($name); $result = DB::table(static::$table) ->whereIn('forum_id', $this->forums) ->where(function (Builder $query) { $query->whereIn('rank_id', $this->ranks) ->orWhere('user_id', $this->user); }) ->whereNotNull($column) ->groupBy($column) ->min($column); $this->permCache[$name] = intval($result) === 1; } return $this->permCache[$name]; } }