Installation via utils/prepare_vendors script (preferred):
Run the project-specific script to symlink the bundle into /src/Awaresoft.
Alternative: Manually clone the repo into /vendor and symlink /src/Awaresoft.
Clear Cache:
php bin/console cache:clear
Register the Bundle:
Add to config/bundles.php:
return [
// ...
Awaresoft\FaqBundle\AwaresoftFaqBundle::class => ['all' => true],
];
Database Setup: Run migrations (if using Doctrine):
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
First Use Case:
Access the FAQ admin panel via /admin/app/faq (SonataAdmin integration).
Create a category (e.g., "General") and add questions/answers.
config/packages/awaresoft_faq.yaml (if auto-generated)./src/Awaresoft/FaqBundle/Entity/ (e.g., FaqCategory, FaqItem)./src/Awaresoft/FaqBundle/Admin/FaqAdmin.php (SonataAdmin configuration).Create/Edit FAQs:
Use the SonataAdmin UI (/admin/app/faq) to manage categories/questions/answers.
Example: Add a "Troubleshooting" category with nested FAQ items.
Custom Fields:
Extend the FaqItem entity to add fields (e.g., isFeatured, priority):
// src/Entity/FaqItemExtension.php
use Doctrine\ORM\Mapping as ORM;
class FaqItemExtension {
/**
* @ORM\Column(type="boolean")
*/
private $isFeatured = false;
}
Update the FaqAdmin class to include the new field in the form.
Twig Integration: Fetch FAQs by category in templates:
{% set faqs = app.service('awaresoft_faq.faq_manager').findByCategory('general') %}
{% for faq in faqs %}
<h3>{{ faq.question }}</h3>
<p>{{ faq.answer }}</p>
{% endfor %}
API Endpoint: Create a controller to expose FAQs as JSON:
// src/Controller/FaqController.php
use Awaresoft\FaqBundle\Manager\FaqManager;
class FaqController extends AbstractController {
public function index(FaqManager $faqManager) {
return $this->json($faqManager->findAll());
}
}
$faqManager->createQueryBuilder('f')
->where('f.question LIKE :query')
->setParameter('query', '%' . $searchTerm . '%')
->getQuery()
->getResult();
// src/DataFixtures/FaqFixtures.php
public function load(ObjectManager $manager) {
$category = new FaqCategory();
$category->setName('Support');
$faq = new FaqItem();
$faq->setQuestion('How do I reset my password?')
->setAnswer('Visit /reset-password.')
->setCategory($category);
$manager->persist($category);
$manager->persist($faq);
$manager->flush();
}
Load fixtures with:
php bin/console doctrine:fixtures:load
Translation Support:
Extend the FaqItem entity to support translations (e.g., using gedmo/translatable):
# config/packages/gedmo_translatable.yaml
gedmo_translatable:
default_lifecycle: translate
Event Listeners: Trigger actions on FAQ updates (e.g., log changes):
// src/EventListener/FaqUpdateListener.php
use Awaresoft\FaqBundle\Entity\FaqItem;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
class FaqUpdateListener implements EventSubscriber {
public function postUpdate(LifecycleEventArgs $args) {
$faq = $args->getObject();
if ($faq instanceof FaqItem) {
// Log or notify about changes
}
}
}
Register in services.yaml:
services:
App\EventListener\FaqUpdateListener:
tags: [doctrine.event_subscriber]
Symlink Issues:
/src/Awaresoft symlink breaks, clear Composer autoload:
composer dump-autoload
autoload_psr4.php removes old vendor paths before symlinking.SonataAdmin Conflicts:
config/bundles.php (SonataAdmin must load before AwaresoftFaqBundle).FaqAdmin.php:
protected function configureTabMenu(TabsMenuBuilder $builder, array $options) {
$builder
->add('List', 'list')
->add('Create', 'create');
}
Doctrine Entity Mapping:
app_is_featured).Version Lock:
Enable Debug Mode:
# config/packages/dev/awaresoft_faq.yaml
awaresoft_faq:
debug: true
Logs SQL queries and admin actions to var/log/dev.log.
Common Errors:
composer dump-autoload.php bin/console doctrine:schema:validate to validate entities.Custom Query Methods:
Add methods to FaqManager:
// src/Manager/FaqManager.php
public function findFeaturedFaqs() {
return $this->createQueryBuilder('f')
->where('f.isFeatured = :featured')
->setParameter('featured', true)
->getQuery()
->getResult();
}
Override Templates:
Copy SonataAdmin templates to templates/bundles/awaresoftfaq/ to customize rendering.
Add Validation:
Extend FaqItem validation in setUp() of FaqAdmin:
protected function configureFormFields(FormMapper $formMapper) {
$formMapper
->add('question', 'text', [
'constraints' => [
new NotBlank(),
new Length(['min' => 10]),
],
]);
}
API Filtering: Use Symfony Serializer for custom JSON output:
// src/Serializer/FaqNormalizer.php
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
class FaqNormalizer implements NormalizerInterface {
public function normalize($object, $format = null, array $context = []) {
return [
'question' => $object->getQuestion(),
'answer' => $object->getAnswer(),
'slug' => $object->getSlug(),
];
}
}
Register in services.yaml:
services:
App\Serializer\FaqNormalizer:
tags: [serializer.normalizer]
Default Category: The bundle may auto-create a "Default" category. Disable in config:
awaresoft_faq:
auto_create_default_category: false
Slug Generation:
Customize slug behavior in FaqItem:
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @Gedmo\Slug(fields={"question"})
*/
private $slug;
Caching: Clear SonataAdmin cache after changes:
php bin/console sonata:admin:cache:clear
How can I help you explore Laravel packages today?