PHPackages                             tourze/question-bank-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. tourze/question-bank-bundle

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

tourze/question-bank-bundle
===========================

题库管理系统：支持题目分类、标签、多种题型和难度管理

0.0.1(6mo ago)04MITPHPCI passing

Since Nov 3Pushed 4mo agoCompare

[ Source](https://github.com/tourze/question-bank-bundle)[ Packagist](https://packagist.org/packages/tourze/question-bank-bundle)[ RSS](/packages/tourze-question-bank-bundle/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (1)Dependencies (39)Versions (2)Used By (0)

QuestionBankBundle
==================

[](#questionbankbundle)

[![PHP 8.1+](https://camo.githubusercontent.com/f870cee2a2e2a442c6b62c8bf79f45ec0ce794dc5af13834902518c9107230f9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e312532422d626c75652e737667)](https://www.php.net)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](https://opensource.org/licenses/MIT)[![Build Status](https://camo.githubusercontent.com/18fe3030b5fe46e64c87ca68500c71cbead90ecc2c29f2ecea04639c7fd01c7e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f796f75722d6f72672f7068702d6d6f6e6f7265706f2f63692e796d6c3f6272616e63683d6d6173746572)](https://github.com/your-org/php-monorepo/actions)[![Coverage Status](https://camo.githubusercontent.com/e3c0a1a1624bec2d356bbcae0c313fd3e3994ee7932f92e5950247ae2eded930/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f796f75722d6f72672f7068702d6d6f6e6f7265706f2e737667)](https://codecov.io/gh/your-org/php-monorepo)

[English](README.md) | [中文](README.zh-CN.md)

A Symfony Bundle focused on question bank management, providing core functionality for storing, organizing, and retrieving questions.

Table of Contents
-----------------

[](#table-of-contents)

- [Features](#features)
- [Installation](#installation)
- [Dependencies](#dependencies)
- [Configuration](#configuration)
- [Quick Start](#quick-start)
- [Core Concepts](#core-concepts)
- [Entity Structure](#entity-structure)
- [Advanced Usage](#advanced-usage)
- [Best Practices](#best-practices)
- [Testing](#testing)
- [Development](#development)
- [FAQ](#faq)
- [Contributing](#contributing)
- [License](#license)

Features
--------

[](#features)

- 🎯 **Focused on Question Management** - Only concerns questions themselves, no exam or practice business logic
- 📝 **Multiple Question Types** - Single choice, multiple choice, true/false, fill-in-the-blank, short answer
- 🏷️ **Flexible Organization** - Multi-category and tag system support
- 🔍 **Powerful Search** - Multi-criteria combined search support
- 📊 **Status Management** - Draft, published, archived states
- 🔒 **Data Validation** - Complete data validation and business rule checking

Installation
------------

[](#installation)

```
composer require tourze/question-bank-bundle
```

Dependencies
------------

[](#dependencies)

This package depends on the following core components:

### System Requirements

[](#system-requirements)

- **PHP**: 8.1 or higher
- **Symfony**: 6.4 or higher
- **Doctrine ORM**: 3.0 or higher

### Bundle Dependencies

[](#bundle-dependencies)

- `doctrine/doctrine-bundle`
- `symfony/framework-bundle`
- `symfony/validator`
- `tourze/doctrine-timestamp-bundle`
- `tourze/doctrine-track-bundle`
- `tourze/doctrine-user-bundle`

Configuration
-------------

[](#configuration)

### Bundle Registration

[](#bundle-registration)

Register the bundle in `config/bundles.php`:

```
return [
    // ...
    Tourze\QuestionBankBundle\QuestionBankBundle::class => ['all' => true],
];
```

### Environment Configuration

[](#environment-configuration)

Configure in `.env` file:

```
# Question Configuration
QUESTION_BANK_MAX_OPTIONS=10              # Max options count (default: 10)
QUESTION_BANK_MAX_CONTENT_LENGTH=5000     # Max content length (default: 5000)

# Category Configuration
QUESTION_BANK_CATEGORY_MAX_DEPTH=5        # Max hierarchy depth (default: 5)
QUESTION_BANK_CATEGORY_CACHE_TTL=3600     # Cache TTL in seconds (default: 3600)

# Tag Configuration
QUESTION_BANK_TAG_MAX_PER_QUESTION=10     # Max tags per question (default: 10)
QUESTION_BANK_TAG_AUTO_SLUG=true          # Auto generate slug (default: true)
```

Quick Start
-----------

[](#quick-start)

### Creating Questions

[](#creating-questions)

```
use Tourze\QuestionBankBundle\DTO\QuestionDTO;
use Tourze\QuestionBankBundle\DTO\OptionDTO;
use Tourze\QuestionBankBundle\Enum\QuestionType;
use Tourze\QuestionBankBundle\Service\QuestionServiceInterface;

// Create question
$questionDTO = new QuestionDTO();
$questionDTO->title = 'Which of the following is a PHP superglobal variable?';
$questionDTO->content = 'Please select the correct answer';
$questionDTO->type = QuestionType::SINGLE_CHOICE;
$questionDTO->difficulty = 2;
$questionDTO->score = 10.0;

// Add options
$questionDTO->options = [
    OptionDTO::create('$_GET', true),
    OptionDTO::create('$get', false),
    OptionDTO::create('$GET', false),
    OptionDTO::create('$_get', false),
];

// Save question
$question = $questionService->createQuestion($questionDTO);
```

### Searching Questions

[](#searching-questions)

```
use Tourze\QuestionBankBundle\DTO\SearchCriteria;
use Tourze\QuestionBankBundle\Enum\QuestionType;

$criteria = new SearchCriteria();
$criteria->setKeyword('PHP')
    ->setTypes([QuestionType::SINGLE_CHOICE])
    ->setMinDifficulty(1)
    ->setMaxDifficulty(3)
    ->setLimit(20);

$result = $questionService->searchQuestions($criteria);
```

### Category Management

[](#category-management)

```
use Tourze\QuestionBankBundle\DTO\CategoryDTO;
use Tourze\QuestionBankBundle\Service\CategoryServiceInterface;

// Create category
$categoryDTO = CategoryDTO::create('Programming Languages', 'programming');
$category = $categoryService->createCategory($categoryDTO);

// Create subcategory
$phpDTO = CategoryDTO::create('PHP', 'php');
$phpDTO->parentId = $category->getId()->toString();
$php = $categoryService->createCategory($phpDTO);
```

Core Concepts
-------------

[](#core-concepts)

### Question Types

[](#question-types)

- **Single Choice** (`SINGLE_CHOICE`) - Only one correct answer
- **Multiple Choice** (`MULTIPLE_CHOICE`) - Can have multiple correct answers
- **True/False** (`TRUE_FALSE`) - Only true/false options
- **Fill in the Blank** (`FILL_IN_THE_BLANK`) - Requires text input
- **Short Answer** (`SHORT_ANSWER`) - Open-ended response

### Question Status

[](#question-status)

- **Draft** (`DRAFT`) - Question is being edited
- **Published** (`PUBLISHED`) - Question is ready for use
- **Archived** (`ARCHIVED`) - Question is disabled

### Difficulty Levels

[](#difficulty-levels)

Question difficulty ranges from 1-5:

- Level 1: Very Easy
- Level 2: Easy
- Level 3: Medium
- Level 4: Hard
- Level 5: Very Hard

Entity Structure
----------------

[](#entity-structure)

### Question

[](#question)

- `id`: Unique identifier
- `title`: Question title
- `content`: Question content
- `type`: Question type
- `difficulty`: Difficulty level
- `score`: Default score
- `explanation`: Answer explanation
- `status`: Publication status

### Option

[](#option)

- `id`: Unique identifier
- `content`: Option content
- `isCorrect`: Whether it's a correct answer
- `sortOrder`: Sort order

### Category

[](#category)

- `id`: Unique identifier
- `name`: Category name
- `code`: Category code
- `parent`: Parent category
- `level`: Hierarchy level
- `path`: Full path

### Tag

[](#tag)

- `id`: Unique identifier
- `name`: Tag name
- `slug`: Tag alias
- `color`: Tag color
- `usageCount`: Usage count

Advanced Usage
--------------

[](#advanced-usage)

### Batch Operations and Transaction Management

[](#batch-operations-and-transaction-management)

```
// Batch question import example
class QuestionBatchImporter
{
    public function importQuestions(array $questionsData): ImportResult
    {
        $result = new ImportResult();

        $this->entityManager->beginTransaction();
        try {
            foreach ($questionsData as $data) {
                $dto = $this->buildQuestionDTO($data);
                $question = $this->questionService->createQuestion($dto);
                $result->addSuccess($question);
            }

            $this->entityManager->commit();
        } catch (\Exception $e) {
            $this->entityManager->rollback();
            $result->addError('Batch import failed', $e->getMessage());
        }

        return $result;
    }
}
```

### Custom Search Engine

[](#custom-search-engine)

```
// Elasticsearch integration
class ElasticsearchQuestionSearcher
{
    public function search(SearchCriteria $criteria): PaginatedResult
    {
        $query = [
            'bool' => [
                'must' => []
            ]
        ];

        // Add keyword search
        if ($criteria->getKeyword()) {
            $query['bool']['must'][] = [
                'multi_match' => [
                    'query' => $criteria->getKeyword(),
                    'fields' => ['title^2', 'content']
                ]
            ];
        }

        // Add category filter
        if ($criteria->getCategoryIds()) {
            $query['bool']['filter'][] = [
                'terms' => ['category_ids' => $criteria->getCategoryIds()]
            ];
        }

        return $this->executeSearch($query, $criteria);
    }
}
```

Best Practices
--------------

[](#best-practices)

1. **Use DTOs for data transfer** - Avoid direct entity manipulation
2. **Operate through service interfaces** - For better testing and extensibility
3. **Use caching wisely** - Category trees and popular tags are good candidates
4. **Use transactions for batch operations** - Ensure data consistency
5. **Listen to events for extensions** - Instead of modifying core code

Testing
-------

[](#testing)

Run the test suite:

```
# Run all tests
./vendor/bin/phpunit packages/question-bank-bundle/tests

# Run unit tests
./vendor/bin/phpunit packages/question-bank-bundle/tests/Unit

# Run integration tests
./vendor/bin/phpunit packages/question-bank-bundle/tests/Integration
```

Development
-----------

[](#development)

### Code Quality Checks

[](#code-quality-checks)

```
# PHPStan static analysis
./vendor/bin/phpstan analyse packages/question-bank-bundle

# Code style check and fix
./vendor/bin/php-cs-fixer fix packages/question-bank-bundle
```

FAQ
---

[](#faq)

### Q: How to implement random question selection?

[](#q-how-to-implement-random-question-selection)

A: Use the QuestionRepository's findRandom method:

```
$randomQuestions = $questionRepository->findRandom(
    limit: 10,
    criteria: $searchCriteria
);
```

### Q: How to implement question versioning?

[](#q-how-to-implement-question-versioning)

A: Listen to question update events:

```
class QuestionVersionListener
{
    public function onQuestionUpdated(QuestionUpdatedEvent $event): void
    {
        $question = $event->getQuestion();
        // Save historical version
        $this->versionService->createSnapshot($question);
    }
}
```

Contributing
------------

[](#contributing)

Welcome to submit Pull Requests and Issues. Please read before development:

1. [Contributing Guide](CONTRIBUTING.md)
2. [Code Style](CODE_STYLE.md)
3. [Testing Guide](TESTING.md)

License
-------

[](#license)

MIT

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance72

Regular maintenance activity

Popularity3

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity25

Early-stage or recently created project

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

187d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/e354fdb316da535dfa8ba2e9193a473c403b6bc6fb9170778d1dc50e304c6e9d?d=identicon)[tourze](/maintainers/tourze)

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/tourze-question-bank-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/tourze-question-bank-bundle/health.svg)](https://phpackages.com/packages/tourze-question-bank-bundle)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M647](/packages/sylius-sylius)[contao/core-bundle

Contao Open Source CMS

1231.6M2.3k](/packages/contao-core-bundle)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[ec-cube/ec-cube

EC-CUBE EC open platform.

78527.0k1](/packages/ec-cube-ec-cube)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

7310.3k29](/packages/open-dxp-opendxp)[netgen/layouts-core

Netgen Layouts enables you to build and manage complex web pages in a simpler way and with less coding. This is the core of Netgen Layouts, its heart and soul.

3689.4k10](/packages/netgen-layouts-core)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
