Installation Add the bundle via Composer:
composer require atm/surveybundle
Register the bundle in config/app.php under providers:
Atm\SurveyBundle\AtmSurveyBundle::class,
Publish Assets & Config Run:
php artisan atm:survey:install
This publishes migrations, translations, and assets to config/packages/atm_survey.yaml and public/vendor/atm_survey/.
Run Migrations
php artisan migrate
This creates tables for surveys, questions, responses, and metadata.
First Survey Creation
Use the admin interface (accessible at /admin/surveys after enabling the route) or create a survey programmatically:
use Atm\SurveyBundle\Entity\Survey;
use Atm\SurveyBundle\Entity\Question;
$survey = new Survey();
$survey->setTitle('Customer Feedback');
$survey->setDescription('Collect feedback from users');
$survey->setActive(true);
$question = new Question();
$question->setText('How satisfied are you?');
$question->setType(Question::TYPE_RADIO);
$question->setOptions(['Very', 'Somewhat', 'Neutral', 'Dissatisfied']);
$survey->addQuestion($question);
$em = $this->getDoctrine()->getManager();
$em->persist($survey);
$em->flush();
Embedding a Survey Use the Twig extension to render a survey:
{{ render_survey(survey.id) }}
Or fetch the URL dynamically:
$survey = $em->getRepository(Survey::class)->find($id);
$url = $this->generateUrl('atm_survey_frontend_show', ['id' => $survey->getId()]);
Dynamic Survey Generation
Use the SurveyBuilder service to construct surveys programmatically:
$builder = $this->get('atm_survey.builder');
$survey = $builder
->setTitle('Onboarding Survey')
->addRadioQuestion('Role', ['Admin', 'User', 'Guest'])
->addTextQuestion('Feedback')
->build();
$em->persist($survey);
Response Handling
Validate and store responses via the SurveyResponseHandler:
$handler = $this->get('atm_survey.response_handler');
$response = $handler->handle($survey, $request->all());
$em->persist($response);
Conditional Logic
Use the Question entity’s setCondition() method to enable branching:
$question->setCondition('previous_question_id', 'answer', 'Admin');
This shows the question only if the previous question’s answer is "Admin".
Exporting Data
Fetch responses via Doctrine or use the SurveyExporter:
$exporter = $this->get('atm_survey.exporter');
$data = $exporter->exportToArray($survey);
Frontend Integration
{{ render_survey(survey.id) }} for embedded forms.return $this->json($this->get('atm_survey.api')->getSurvey($id));
Atm\SurveyBundle\Form\Type\SurveyType) for custom validation.survey.response.created or survey.published events for post-processing:
$dispatcher->addListener('survey.response.created', function ($event) {
// Send email, log analytics, etc.
});
config/packages/atm_survey.yaml:
atm_survey:
translations:
en: '%kernel.project_dir%/translations/survey.en.yaml'
Migration Conflicts
vendor/. Instead, extend the entities in your project:
namespace App\Entity;
use Atm\SurveyBundle\Entity\Survey as BaseSurvey;
class Survey extends BaseSurvey {}
php artisan atm:survey:install --force to republish migrations if needed.Caching Issues
php artisan cache:clear
# config/packages/atm_survey.yaml
atm_survey:
cache_enabled: false
CSRF Token Mismatch
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
Question Type Limitations
QuestionType class:
namespace App\Form\Type;
use Atm\SurveyBundle\Form\Type\QuestionType as BaseType;
class CustomQuestionType extends BaseType {
public function getParent() { return 'atm_survey_question'; }
// Add custom logic here
}
config/packages/atm_survey.yaml:
atm_survey:
form_types:
custom: App\Form\Type\CustomQuestionType
Database Locking
$em->beginTransaction();
try {
// Bulk operations
$em->commit();
} catch (\Exception $e) {
$em->rollBack();
throw $e;
}
Enable Debug Mode
Set debug: true in config/packages/atm_survey.yaml to log SQL queries and validation errors.
Check the Admin Panel
The /admin/surveys route provides a dashboard for testing surveys, responses, and configurations.
Log Responses
Override the ResponseHandler to log raw data:
$handler = $this->get('atm_survey.response_handler');
$handler->setLogger($this->get('logger'));
Validate Entities Use Symfony’s validator to catch issues early:
$errors = $validator->validate($survey);
if (count($errors) > 0) {
foreach ($errors as $error) {
$this->addFlash('error', $error->getMessage());
}
}
Custom Survey Storage
Implement Atm\SurveyBundle\Storage\SurveyStorageInterface to use a non-DB backend (e.g., Elasticsearch).
Response Processing
Extend Atm\SurveyBundle\Event\SurveyResponseEvent to add logic after response submission.
Frontend Templates
Override Twig templates in templates/AtmSurveyBundle/ to customize rendering.
API Endpoints Create custom controllers to expose surveys/response via GraphQL or REST:
use Atm\SurveyBundle\Entity\Survey;
use Symfony\Component\HttpFoundation\JsonResponse;
class SurveyApiController extends AbstractController {
public function getSurvey(Survey $survey): JsonResponse {
return $this->json($survey->toArray());
}
}
How can I help you explore Laravel packages today?