em = $entityManager; } protected function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'query_limit' => 75, 'return_limit' => 25, 'min_keyword_length' => 3, ]); } /** * Search tags that begins with the certain keyword. * * @param string $keyword The keyword the tag must begin with * @param array $options Some options specifying the search behavior. See configureOptions for possible options. * * @return string[] An array containing the tags that match the given keyword. */ public function searchTags(string $keyword, array $options = []) { $results = []; $keyword_regex = '/^'.preg_quote($keyword, '/').'/'; $resolver = new OptionsResolver(); $this->configureOptions($resolver); $options = $resolver->resolve($options); //If the keyword is too short we will get to much results, which takes too much time... if (mb_strlen($keyword) < $options['min_keyword_length']) { return []; } //Build a query to get all $qb = $this->em->createQueryBuilder(); $qb->select('p.tags') ->from(Part::class, 'p') ->where('p.tags LIKE ?1') ->setMaxResults($options['query_limit']) //->orderBy('RAND()') ->setParameter(1, '%'.$keyword.'%'); $possible_tags = $qb->getQuery()->getArrayResult(); //Iterate over each possible tags (which are comma separated) and extract tags which match our keyword foreach ($possible_tags as $tags) { $tags = explode(',', $tags['tags']); $results = array_merge($results, preg_grep($keyword_regex, $tags)); } $results = array_unique($results); //Limit the returned tag count to specified value. return \array_slice($results, 0, $options['return_limit']); } }