src/Dto/SearchOptions.php line 15

Open in your IDE?
  1. <?php
  2. /*
  3.  * Author: Dominik Piekarski <code@dompie.de>
  4.  * Created at: 2020/10/13 12:23
  5.  */
  6. declare(strict_types=1);
  7. namespace App\Dto;
  8. use App\Dictionary\Content;
  9. use App\Dictionary\SearchType;
  10. use App\Form\Search\GlobalSearch;
  11. use Symfony\Component\HttpFoundation\InputBag;
  12. class SearchOptions
  13. {
  14.     private const DEFAULT_SUGGEST_SEARCH false;
  15.     private const DEFAULT_SEARCH_TYPE SearchType::ALL;
  16.     private const DEFAULT_PAGE 1;
  17.     private const DEFAULT_PER_PAGE 9;
  18.     public const DEFAULT_REGION SearchType::ALL;
  19.     public const DEFAULT_AGE SearchType::ALL;
  20.     public const DEFAULT_MIN_AGE 18;
  21.     public const DEFAULT_MAX_AGE 127;
  22.     public const DEFAULT_ONLINE SearchType::ALL;
  23.     public const ONLINE_ONLY 'on';
  24.     public const ONLINE_LIVECAM 'livecam';
  25.     public const DEFAULT_GENDER SearchType::ALL;
  26.     public const DEFAULT_MEMBER_TYPE SearchType::ALL;
  27.     public const MEMBER_TYPE_AMATEUR 'amateur';
  28.     public const MEMBER_TYPE_MEMBER 'member';
  29.     private const DEFAULT_TERM '';
  30.     public const DEFAULT_VIDEO_RESOLUTION 0;
  31.     public const DEFAULT_SINCE 0;
  32.     public const DEFAULT_MIN_RATING 0.0;
  33.     public const DEFAULT_MAX_RATING 5.0;
  34.     public const DEFAULT_MIN_DURATION 0;
  35.     public const DEFAULT_MAX_DURATION 32000;
  36.     private const MAX_PER_PAGE 200;
  37.     private const MAX_TERM_LENGTH 200;
  38.     public const DEFAULT_MIN_IMAGES 10;
  39.     public const DEFAULT_MAX_IMAGES 300;
  40.     public array $options = [];
  41.     public function __construct()
  42.     {
  43.         $this->initDefaults();
  44.     }
  45.     public function setSuggestSearch(bool $do self::DEFAULT_SUGGEST_SEARCH): self
  46.     {
  47.         $this->options['isSuggest'] = $do;
  48.         return $this;
  49.     }
  50.     public function isSuggestSearch(): bool
  51.     {
  52.         return $this->options['isSuggest'] ?? self::DEFAULT_SUGGEST_SEARCH;
  53.     }
  54.     public function getOnline(): string
  55.     {
  56.         return $this->options['online'] ?? self::DEFAULT_ONLINE;
  57.     }
  58.     public function isOnlineOnly(): bool
  59.     {
  60.         return $this->getOnline() === self::ONLINE_ONLY;
  61.     }
  62.     public function isWebcamOnly(): bool
  63.     {
  64.         return $this->getOnline() === self::ONLINE_LIVECAM;
  65.     }
  66.     public function setOnline(string $online): self
  67.     {
  68.         $this->options['online'] = $online;
  69.         return $this;
  70.     }
  71.     public function hasOnlineFilter(): bool
  72.     {
  73.         return $this->getOnline() !== self::DEFAULT_ONLINE;
  74.     }
  75.     public function setProfilePhotoOnly(string $value): self
  76.     {
  77.         $this->options['withProfilePhotoOnly'] = true;
  78.         return $this;
  79.     }
  80.     public function getProfilePhotoOnly(): bool
  81.     {
  82.         return $this->options['withProfilePhotoOnly'] ?? false;
  83.     }
  84.     public function isProfilePhotoOnly(): bool
  85.     {
  86.         return $this->getProfilePhotoOnly();
  87.     }
  88.     public function getTerm(bool $lowercase true): string
  89.     {
  90.         $term $this->options['term'] ?? self::DEFAULT_TERM;
  91.         if ($lowercase) {
  92.             return mb_strtolower($term);
  93.         }
  94.         return $term;
  95.     }
  96.     public function setTerm($term ''): self
  97.     {
  98.         $this->options['term'] = mb_substr((string)$term0self::MAX_TERM_LENGTH);
  99.         return $this;
  100.     }
  101.     public function getSearchType(): string
  102.     {
  103.         return $this->options['searchType'] ?? self::DEFAULT_SEARCH_TYPE;
  104.     }
  105.     public function setSearchType(string $searchType self::DEFAULT_SEARCH_TYPE): self
  106.     {
  107.         $this->options['searchType'] = $searchType;
  108.         return $this;
  109.     }
  110.     public function getMemberType(): string
  111.     {
  112.         return $this->options['memberType'] ?? self::DEFAULT_MEMBER_TYPE;
  113.     }
  114.     public function setMemberType(string $memberType self::DEFAULT_MEMBER_TYPE): self
  115.     {
  116.         $this->options['memberType'] = $memberType;
  117.         return $this;
  118.     }
  119.     public function hasMemberTypeFilter(): bool
  120.     {
  121.         return $this->getMemberType() !== self::DEFAULT_MEMBER_TYPE;
  122.     }
  123.     public function isAmateurOnly(): bool
  124.     {
  125.         return $this->getMemberType() === self::MEMBER_TYPE_AMATEUR;
  126.     }
  127.     public function getMemberSex(): string
  128.     {
  129.         return $this->options['memberSex'] ?? self::DEFAULT_GENDER;
  130.     }
  131.     public function setMemberSex(string $memberSex self::DEFAULT_GENDER): self
  132.     {
  133.         $this->options['memberSex'] = $memberSex;
  134.         return $this;
  135.     }
  136.     public function hasMemberSexFilter(): bool
  137.     {
  138.         return $this->getMemberSex() !== self::DEFAULT_GENDER;
  139.     }
  140.     public function getRegion(): string
  141.     {
  142.         return $this->options['region'] ?? self::DEFAULT_REGION;
  143.     }
  144.     public function setRegion(?string $region): self
  145.     {
  146.         $this->options['region'] = $region;
  147.         return $this;
  148.     }
  149.     public function hasRegionFilter(): bool
  150.     {
  151.         return $this->getRegion() !== self::DEFAULT_REGION;
  152.     }
  153.     public function setPage(int $page): self
  154.     {
  155.         $this->options['page'] = $page;
  156.         return $this;
  157.     }
  158.     public function getPage(): int
  159.     {
  160.         return $this->options['page'] ?? self::DEFAULT_PAGE;
  161.     }
  162.     public function setPerPage(int $perPage self::DEFAULT_PER_PAGE): self
  163.     {
  164.         $this->options['perPage'] = $perPage self::MAX_PER_PAGE self::MAX_PER_PAGE $perPage;
  165.         return $this;
  166.     }
  167.     public function getPerPage(): int
  168.     {
  169.         return $this->options['perPage'] ?? self::DEFAULT_PER_PAGE;
  170.     }
  171.     public function fromGlobalSearch(InputBag $bag): void
  172.     {
  173.         $formBlockPrefix GlobalSearch::BLOCK_PREFIX;
  174.         if (!$bag->has($formBlockPrefix)) {
  175.             $this->initDefaults();
  176.             return;
  177.         }
  178.         $params $bag->get($formBlockPrefix);
  179.         $searchType self::DEFAULT_SEARCH_TYPE;
  180.         if (isset($params['searchType']) && in_array((string)$params['searchType'], [SearchType::IMAGESETSearchType::VIDEOSearchType::MEMBERSearchType::ALL], true)) {
  181.             $searchType = (string)$params['searchType'];
  182.         }
  183.         $this->setPage($bag->getInt('page'self::DEFAULT_PAGE));
  184.         $this->setPerPage($bag->getInt('perPage'self::DEFAULT_PER_PAGE));
  185.         $this->setSearchType($searchType);
  186.         $this->setTerm($params['term'] ?? self::DEFAULT_TERM);
  187.     }
  188.     public function fromQuery(InputBag $bag): void
  189.     {
  190.         $params $bag->all();
  191.         $searchType self::DEFAULT_SEARCH_TYPE;
  192.         if (isset($params['searchType']) && in_array((string)$params['searchType'], [SearchType::IMAGESETSearchType::VIDEOSearchType::MEMBERSearchType::ALL], true)) {
  193.             $searchType = (string)$params['searchType'];
  194.         }
  195.         $this->pageFromQuery($bag);
  196.         $this->setPerPage($bag->getInt('perPage'self::DEFAULT_PER_PAGE));
  197.         $this->setSearchType($searchType);
  198.         $this->setTerm($params['term'] ?? self::DEFAULT_TERM);
  199.     }
  200.     public function pageFromQuery(InputBag $bag): void
  201.     {
  202.         $this->setPage($bag->getInt('page'self::DEFAULT_PAGE));
  203.     }
  204.     public function applySorting(InputBag $bag): self
  205.     {
  206.         switch ($bag->get('o')) {
  207.             case 'newest':
  208.                 $this->setOrderByNewest('desc');
  209.                 break;
  210.             case 'rating':
  211.                 $this->setOrderByRating('desc');
  212.                 break;
  213.             case 'duration':
  214.                 $this->setOrderByDuration('asc');
  215.                 break;
  216.             case 'daily':
  217.                 $this->setOrderByDaily();
  218.                 break;
  219.         }
  220.         return $this;
  221.     }
  222.     /*
  223.      * Video resolution
  224.      */
  225.     public function getResolution(): int
  226.     {
  227.         return $this->options['resolution'] ?? self::DEFAULT_VIDEO_RESOLUTION;
  228.     }
  229.     public function setResolution(int $resolution): self
  230.     {
  231.         $this->options['resolution'] = $resolution;
  232.         return $this;
  233.     }
  234.     public function isResolution360p(): bool
  235.     {
  236.         return $this->getResolution() === Content::VIDEO_360;
  237.     }
  238.     public function isResolution720p(): bool
  239.     {
  240.         return $this->getResolution() === Content::VIDEO_720;
  241.     }
  242.     public function isResolution1080p(): bool
  243.     {
  244.         return $this->getResolution() === Content::VIDEO_1080;
  245.     }
  246.     public function getSince(): int
  247.     {
  248.         return $this->options['since'] ?? self::DEFAULT_SINCE;
  249.     }
  250.     public function setSince(int $since): self
  251.     {
  252.         $this->options['since'] = $since;
  253.         return $this;
  254.     }
  255.     public function hasSinceFilter(): bool
  256.     {
  257.         return $this->getSince() !== self::DEFAULT_SINCE;
  258.     }
  259.     public function setMinRating(?float $rating): self
  260.     {
  261.         $this->options['minRating'] = $rating;
  262.         return $this;
  263.     }
  264.     public function getMinRating(): ?float
  265.     {
  266.         return $this->options['minRating'] ?? self::DEFAULT_MIN_RATING;
  267.     }
  268.     public function setMaxRating(?float $rating): self
  269.     {
  270.         $this->options['maxRating'] = $rating;
  271.         return $this;
  272.     }
  273.     public function getMaxRating(): ?float
  274.     {
  275.         return $this->options['maxRating'] ?? self::DEFAULT_MAX_RATING;
  276.     }
  277.     public function hasRatingFilter(): bool
  278.     {
  279.         return $this->getMinRating() !== self::DEFAULT_MIN_RATING || $this->getMaxRating() !== self::DEFAULT_MAX_RATING;
  280.     }
  281.     public function setMinAge(int $age): self
  282.     {
  283.         $this->options['minAge'] = $age self::DEFAULT_MIN_AGE self::DEFAULT_MIN_AGE $age;
  284.         return $this;
  285.     }
  286.     public function getMinAge(): int
  287.     {
  288.         if (!isset($this->options['minAge']) || $this->options['minAge'] < self::DEFAULT_MIN_AGE) {
  289.             return self::DEFAULT_MIN_AGE;
  290.         }
  291.         return $this->options['minAge'];
  292.     }
  293.     public function setMaxAge(int $age): self
  294.     {
  295.         $this->options['maxAge'] = $age self::DEFAULT_MAX_AGE self::DEFAULT_MAX_AGE $age;
  296.         return $this;
  297.     }
  298.     public function getMaxAge(): int
  299.     {
  300.         return $this->options['maxAge'] ?? self::DEFAULT_MAX_AGE;
  301.     }
  302.     public function hasAgeFilter(): bool
  303.     {
  304.         return $this->getMinAge() !== self::DEFAULT_MIN_AGE || $this->getMaxAge() !== self::DEFAULT_MAX_AGE;
  305.     }
  306.     public function setMinLength(?int $length): self
  307.     {
  308.         $this->options['minLength'] = $length;
  309.         return $this;
  310.     }
  311.     public function getMinLength(): int
  312.     {
  313.         return $this->options['minLength'] ?? self::DEFAULT_MIN_DURATION;
  314.     }
  315.     public function setMaxLength(int $length): self
  316.     {
  317.         $this->options['maxLength'] = $length self::DEFAULT_MAX_DURATION self::DEFAULT_MAX_DURATION $length;
  318.         return $this;
  319.     }
  320.     public function getMaxLength(): ?int
  321.     {
  322.         return $this->options['maxLength'] ?? self::DEFAULT_MAX_DURATION;
  323.     }
  324.     public function hasLengthFilter(): bool
  325.     {
  326.         return $this->getMinLength() !== self::DEFAULT_MIN_DURATION || $this->getMaxLength() !== self::DEFAULT_MAX_DURATION;
  327.     }
  328.     public function getMinImages(): int
  329.     {
  330.         return $this->options['minImages'] ?? self::DEFAULT_MIN_IMAGES;
  331.     }
  332.     public function setMinImages(int $minImages): self
  333.     {
  334.         $this->options['minImages'] = $minImages;
  335.         return $this;
  336.     }
  337.     public function hasImagesFilter(): bool
  338.     {
  339.         return $this->getMinImages() >= self::DEFAULT_MIN_IMAGES || $this->getMaxImages() !== self::DEFAULT_MAX_IMAGES;
  340.     }
  341.     public function getMaxImages(): int
  342.     {
  343.         return $this->options['maxImages'] ?? self::DEFAULT_MAX_IMAGES;
  344.     }
  345.     public function setMaxImages(int $maxImages): self
  346.     {
  347.         $this->options['maxImages'] = $maxImages;
  348.         return $this;
  349.     }
  350.     public function initDefaults(): self
  351.     {
  352.         $this->options = [];
  353.         $this->setTerm(self::DEFAULT_TERM);
  354.         return $this;
  355.     }
  356.     public function setOrderByNewest(?string $direction): self
  357.     {
  358.         if ($direction) {
  359.             $this->options['orderBy']['since'] = $direction === 'asc' 'asc' 'desc';
  360.         }
  361.         return $this;
  362.     }
  363.     public function getOrderByNewest(): ?string
  364.     {
  365.         return $this->options['orderBy']['since'] ?? null;
  366.     }
  367.     public function setOrderByRating(?string $direction): self
  368.     {
  369.         if ($direction) {
  370.             $this->options['orderBy']['rating'] = $direction === 'asc' 'asc' 'desc';
  371.         }
  372.         return $this;
  373.     }
  374.     public function getOrderByRating(): ?string
  375.     {
  376.         return $this->options['orderBy']['rating'] ?? null;
  377.     }
  378.     public function setOrderByDuration(?string $direction 'asc'): self
  379.     {
  380.         if ($direction) {
  381.             $this->options['orderBy']['duration'] = $direction === 'desc' 'desc' 'asc';
  382.         }
  383.         return $this;
  384.     }
  385.     public function getOrderByDuration(): ?string
  386.     {
  387.         return $this->options['orderBy']['duration'] ?? null;
  388.     }
  389.     public function getOrderByDefault(): bool
  390.     {
  391.         return $this->getOrderByDaily() === false &&
  392.             is_string($this->getOrderByRating()) === false &&
  393.             is_string($this->getOrderByNewest()) === false &&
  394.             is_string($this->getOrderByDuration()) === false;
  395.     }
  396.     /**
  397.      * Every day another random order
  398.      * @return $this
  399.      */
  400.     public function setOrderByDaily(): self
  401.     {
  402.         $this->options['orderBy']['daily'] = true;
  403.         return $this;
  404.     }
  405.     public function getOrderByDaily(): bool
  406.     {
  407.         return $this->options['orderBy']['daily'] ?? false;
  408.     }
  409. }