You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			218 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			PHP
		
	
			
		
		
	
	
			218 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			PHP
		
	
<?php
 | 
						|
	/**
 | 
						|
	 * \file
 | 
						|
	 * Provide filters for Session Communities.
 | 
						|
	 */
 | 
						|
 | 
						|
	require_once 'php/servers/servers-rooms.php';
 | 
						|
	require_once 'php/utils/utils.php';
 | 
						|
	require_once 'php/servers/room-listings-api.php';
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Filters Session Communities.
 | 
						|
	 *
 | 
						|
	 * RoomSieve methods return copies when mutating the object.
 | 
						|
	 * The stickied room list is preserved after filtering.
 | 
						|
	 */
 | 
						|
	class RoomSieve {
 | 
						|
		/**
 | 
						|
		 * Communities stored.
 | 
						|
		 *
 | 
						|
		 * @var CommunityRoom[] $rooms;
 | 
						|
		 */
 | 
						|
		private array $rooms;
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Pinned Communities, set aside.
 | 
						|
		 *
 | 
						|
		 * Not affected by filters.
 | 
						|
		 *
 | 
						|
		 * @var CommunityRoom[] $stickied
 | 
						|
		 */
 | 
						|
		private array $stickies;
 | 
						|
 | 
						|
		/**
 | 
						|
		 * @param CommunityRoom[] $rooms
 | 
						|
		 * @param CommunityRoom[] $stickied
 | 
						|
		 */
 | 
						|
		private function __construct(array $rooms, array $stickied = []) {
 | 
						|
			$this->rooms = $rooms;
 | 
						|
			$this->stickies = $stickied;
 | 
						|
		}
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Default limit for number of Communities.
 | 
						|
		 *
 | 
						|
		 * Applies only to certain functions.
 | 
						|
		 */
 | 
						|
		public const TOP_DEFAULT = 35;
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Create new RoomSieve from the given Communities.
 | 
						|
		 *
 | 
						|
		 * @param CommunityRoom[] $rooms
 | 
						|
		 *
 | 
						|
		 * @return RoomSieve
 | 
						|
		 */
 | 
						|
		public static function takeRooms(array $rooms): RoomSieve {
 | 
						|
			return new RoomSieve($rooms);
 | 
						|
		}
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Set aside pinned Communities from the main list.
 | 
						|
		 *
 | 
						|
		 * @return RoomSieve
 | 
						|
		 */
 | 
						|
		public function saveStickies(): self {
 | 
						|
			$stickied = CommunityRoom::get_stickied_rooms($this->rooms, $rest);
 | 
						|
			$rooms = $rest;
 | 
						|
			return $this->cloneWith($rooms, $stickied);
 | 
						|
		}
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Add the given Communities to a new RoomSieve.
 | 
						|
		 *
 | 
						|
		 * @param CommunityRoom[] $rooms
 | 
						|
		 *
 | 
						|
		 * @return RoomSieve
 | 
						|
		 */
 | 
						|
		public function addRooms(array $rooms): RoomSieve {
 | 
						|
			return $this->cloneWith(array_merge($this->rooms, $rooms));
 | 
						|
		}
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Use a custom filter for Communities.
 | 
						|
		 *
 | 
						|
		 * Creates a new RoomSieve with all Communities that passed the filter.
 | 
						|
		 *
 | 
						|
		 * @param Closure $filter Function which takes an array of Communities and returns an array of Communities.
 | 
						|
		 *
 | 
						|
		 * @return RoomSieve
 | 
						|
		 */
 | 
						|
		public function apply(Closure $filter): RoomSieve {
 | 
						|
			return $this->cloneWith($filter($this->rooms));
 | 
						|
		}
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Return all stored Communities, including pinned Communities.
 | 
						|
		 *
 | 
						|
		 * @return CommunityRoom[]
 | 
						|
		 */
 | 
						|
		public function getWithStickies(): array {
 | 
						|
			return [...$this->stickies, ...$this->rooms];
 | 
						|
		}
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Return stored Communities without pinned Communities.
 | 
						|
		 *
 | 
						|
		 * @return CommunityRoom[]
 | 
						|
		 */
 | 
						|
		public function getWithoutStickies(): array {
 | 
						|
			return $this->saveStickies()->rooms;
 | 
						|
		}
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Only keep the top N active Communities.
 | 
						|
		 *
 | 
						|
		 * Does not affect stickied Communities.
 | 
						|
		 *
 | 
						|
		 * @param int $count Number of top Communities to keep. (optional)
 | 
						|
		 *
 | 
						|
		 * @return RoomSieve
 | 
						|
		 */
 | 
						|
		public function onlyTop(int $count = RoomSieve::TOP_DEFAULT): RoomSieve {
 | 
						|
			$rooms = $this->rooms;
 | 
						|
			CommunityRoom::sort_rooms_num($rooms, 'active_users', descending: true);
 | 
						|
			return $this->cloneWith(array_slice($rooms, 0, $count));
 | 
						|
		}
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Remove the top N active Communities.
 | 
						|
		 *
 | 
						|
		 * Does not affect stickied Communities.
 | 
						|
		 *
 | 
						|
		 * @param int $count Number of top Communities to remove. (optional)
 | 
						|
		 *
 | 
						|
		 * @return RoomSieve
 | 
						|
		 */
 | 
						|
		public function exceptTop(int $count = RoomSieve::TOP_DEFAULT): RoomSieve {
 | 
						|
			$rooms = $this->rooms;
 | 
						|
			CommunityRoom::sort_rooms_num($rooms, 'active_users', descending: true);
 | 
						|
			return $this->cloneWith(array_slice($rooms, $count));
 | 
						|
		}
 | 
						|
 | 
						|
		private static function isIndexApproved(CommunityRoom $room): bool {
 | 
						|
			return (
 | 
						|
				!$room->rated_nsfw() &&
 | 
						|
				$room->write &&
 | 
						|
				!$room->has_poor_staff_rating() &&
 | 
						|
				!empty($room->description)
 | 
						|
			);
 | 
						|
		}
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Sort Communities by name and server.
 | 
						|
		 *
 | 
						|
		 * @return RoomSieve
 | 
						|
		 */
 | 
						|
		public function applyStandardSort(): RoomSieve {
 | 
						|
			$rooms = $this->rooms;
 | 
						|
			CommunityRoom::sort_rooms_str($rooms, 'name');
 | 
						|
			CommunityRoom::sort_rooms_by_server($rooms);
 | 
						|
			return new RoomSieve($rooms, $this->stickies);
 | 
						|
		}
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Sort Communities by staff rating.
 | 
						|
		 *
 | 
						|
		 * Communities with a description are also preferred.
 | 
						|
		 *
 | 
						|
		 * @return RoomSieve
 | 
						|
		 */
 | 
						|
		public function applyPreferentialSort(): RoomSieve {
 | 
						|
			$rooms = $this->rooms;
 | 
						|
			CommunityRoom::sort_rooms_num($rooms,'created');
 | 
						|
			usort($rooms, function($a, $b) {
 | 
						|
				return empty($b->description) - empty($a->description);
 | 
						|
			});
 | 
						|
			usort($rooms, function(CommunityRoom $a, CommunityRoom $b) {
 | 
						|
				return sign($a->get_numeric_staff_rating() - $b->get_numeric_staff_rating());
 | 
						|
			});
 | 
						|
			return new RoomSieve(array_reverse($rooms), $this->stickies);
 | 
						|
		}
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Keep only Communities heuristically deemed to be appropriate.
 | 
						|
		 *
 | 
						|
		 * @return RoomSieve
 | 
						|
		 */
 | 
						|
		public function indexApproved(): RoomSieve {
 | 
						|
			$rooms = array_values(array_filter($this->rooms, function($room) {
 | 
						|
				return RoomSieve::isIndexApproved($room);
 | 
						|
			}));
 | 
						|
			return new RoomSieve($rooms, $this->stickies);
 | 
						|
		}
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Remove Communities heuristically deemed to be appropriate.
 | 
						|
		 *
 | 
						|
		 * @return RoomSieve
 | 
						|
		 */
 | 
						|
		public function indexNonApproved(): RoomSieve {
 | 
						|
			$rooms = array_values(array_filter($this->rooms, function($room) {
 | 
						|
				return !RoomSieve::isIndexApproved($room);
 | 
						|
			}));
 | 
						|
			return new RoomSieve($rooms, $this->stickies);
 | 
						|
		}
 | 
						|
 | 
						|
		private function clone(): self {
 | 
						|
			return $this->cloneWith();
 | 
						|
		}
 | 
						|
 | 
						|
		private function cloneWith($rooms = null, $stickies = null): self {
 | 
						|
			$clone = new RoomSieve($rooms ?? $this->rooms, $stickies ?? $this->stickies);
 | 
						|
			return $clone;
 | 
						|
		}
 | 
						|
	}
 | 
						|
?>
 |