Installation:
composer require ekyna/survey-bundle
Add to config/bundles.php:
Ekyna\SurveyBundle\EkynaSurveyBundle::class => ['all' => true],
Database Migration:
Run migrations (check vendor/ekyna/survey-bundle/migrations/ for SQL files or adapt to Laravel’s schema builder).
First Use Case:
Create a survey via the bundle’s CLI or manually via the Survey model:
use Ekyna\SurveyBundle\Entity\Survey;
$survey = new Survey();
$survey->setTitle('Customer Feedback');
$survey->setDescription('Quick feedback on our service');
$survey->setActive(true);
$survey->setCreatedAt(new \DateTime());
$surveyManager->saveSurvey($survey); // Inject SurveyManager service
Key Classes to Explore:
SurveyManager: Core service for CRUD operations.Question/Answer entities: Define survey structure.SurveyResponse: Store participant submissions.Survey Creation:
SurveyManager to create surveys programmatically or via a form (e.g., Symfony forms in Laravel’s context).$question = new \Ekyna\SurveyBundle\Entity\Question();
$question->setTitle('How satisfied are you?');
$question->setType('multiple_choice'); // Limited to basic types per README
$question->addAnswer(new \Ekyna\SurveyBundle\Entity\Answer('Very satisfied'));
$survey->addQuestion($question);
Participant Responses:
SurveyResponse:
$response = new \Ekyna\SurveyBundle\Entity\SurveyResponse();
$response->setSurvey($survey);
$response->setParticipantEmail('user@example.com');
$response->setSubmittedAt(new \DateTime());
$response->addAnswer(new \Ekyna\SurveyBundle\Entity\ResponseAnswer($question, 'Very satisfied'));
$surveyManager->saveResponse($response);
Displaying Surveys:
$activeSurveys = $surveyManager->findActiveSurveys();
@foreach($survey->getQuestions() as $question)
<h3>{{ $question->getTitle() }}</h3>
@foreach($question->getAnswers() as $answer)
<label>{{ $answer->getText() }}</label>
@endforeach
@endforeach
Integration with Laravel:
AppServiceProvider:
$this->app->bind(
\Ekyna\SurveyBundle\Manager\SurveyManager::class,
\Ekyna\SurveyBundle\Manager\SurveyManager::class
);
public function handle($request, Closure $next) {
if (!$request->user()) abort(403);
return $next($request);
}
API Endpoints (if needed):
Route::get('/surveys/{id}', [SurveyController::class, 'show']);
Outdated Codebase:
text or integer. Only basic types (e.g., multiple_choice) may work out-of-the-box.Database Schema:
Schema::create('survey_questions', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('type')->default('multiple_choice');
// ... other fields
});
Service Injection:
No Built-in Admin Panel:
php artisan tinker
>>> $survey = new \Ekyna\SurveyBundle\Entity\Survey();
>>> $survey->setTitle('Test');
>>> $surveyManager->saveSurvey($survey);
Responses vs. Submissions:
SurveyResponse (participant submissions) and ResponseAnswer (individual answers). Ensure data is saved hierarchically:
$response->addAnswer(new \Ekyna\SurveyBundle\Entity\ResponseAnswer($question, $selectedAnswerText));
Enable Debugging:
\Log::info('Survey saved', ['id' => $survey->getId()]);
Check Entity Relationships:
dd() to inspect relationships:
dd($survey->getQuestions()->first()->getAnswers());
Override Bundle Classes:
Survey) to add missing methods:
namespace App\Entity;
use Ekyna\SurveyBundle\Entity\Survey as BaseSurvey;
class Survey extends BaseSurvey {
public function getActiveQuestions() {
return $this->getQuestions()->filter(fn($q) => $q->isActive());
}
}
Custom Question Types:
Question entity to support new types (e.g., text, rating):
namespace App\Entity;
use Ekyna\SurveyBundle\Entity\Question as BaseQuestion;
class Question extends BaseQuestion {
const TYPE_RATING = 'rating';
public function isRatingQuestion() {
return $this->getType() === self::TYPE_RATING;
}
}
Validation:
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'answers.*' => 'required',
]);
Events:
event(new \App\Events\SurveySubmitted($response));
Testing:
public function test_survey_submission() {
$response = $this->post('/surveys/1/submit', [
'answers' => ['q1' => 'option1']
]);
$response->assertStatus(200);
}
How can I help you explore Laravel packages today?