Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Reports Bundle Laravel Package

bisonlab/reports-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require bisonlab/reports-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        BisonLab\ReportsBundle\BisonLabReportsBundle::class => ['all' => true],
    ];
    
  2. First Use Case: Basic Report Define a report service (e.g., src/Service/MyReportService.php):

    namespace App\Service;
    
    use BisonLab\ReportsBundle\Report\ReportInterface;
    
    class MyReportService implements ReportInterface
    {
        public function getName(): string
        {
            return 'my_report';
        }
    
        public function getTitle(): string
        {
            return 'My Custom Report';
        }
    
        public function getContent(): string
        {
            return $this->renderData(); // Your logic here
        }
    }
    
  3. Register the Service Add to services.yaml:

    services:
        App\Service\MyReportService:
            tags: [bisonlab.reports.report]
    
  4. Access the Report Route to the report viewer:

    // src/Controller/ReportController.php
    use BisonLab\ReportsBundle\Controller\ReportController;
    
    class ReportController extends ReportController
    {
        public function indexAction()
        {
            return $this->renderReport('my_report');
        }
    }
    

    Visit /report/my_report in your browser.


Implementation Patterns

Service-Based Workflow

  1. Report Interface Implement ReportInterface for all reports:

    class UserActivityReport implements ReportInterface
    {
        public function getName(): string { return 'user_activity'; }
        public function getTitle(): string { return 'User Activity Log'; }
        public function getContent(): string { return $this->generateCsv(); }
    }
    
  2. Dependency Injection Inject services into reports:

    class SalesReport implements ReportInterface
    {
        public function __construct(private SalesService $salesService) {}
    
        public function getContent(): string
        {
            $data = $this->salesService->getMonthlySales();
            return $this->renderTemplate($data);
        }
    }
    
  3. Dynamic Data Binding Use getParameters() to accept user input:

    public function getParameters(): array
    {
        return [
            'start_date' => '2023-01-01',
            'end_date'   => '2023-12-31',
        ];
    }
    

    Access via Request in controller:

    $this->renderReport('sales', ['start_date' => $request->query->get('date')]);
    
  4. Template Integration Use Twig for dynamic content:

    public function getContent(): string
    {
        return $this->twig->render('reports/sales.html.twig', [
            'data' => $this->fetchData(),
        ]);
    }
    
  5. Export Formats Extend ReportInterface for custom exports:

    class PdfReport implements ReportInterface
    {
        public function getContent(): string
        {
            return $this->dompdf->loadHtml($this->renderHtml())->output();
        }
    }
    

Gotchas and Tips

Common Pitfalls

  1. Service Tagging

    • Forgetting to tag services with bisonlab.reports.report will make them invisible to the bundle.
    • Fix: Verify tags in services.yaml or via debug:container.
  2. Caching Reports

    • Reports are cached by default. Clear cache after changes:
      php bin/console cache:clear
      
    • Disable caching for dynamic reports:
      # config/packages/bisonlab_reports.yaml
      bisonlab_reports:
          cache: false
      
  3. Parameter Validation

    • No built-in validation for getParameters(). Use Symfony Validator:
      use Symfony\Component\Validator\Constraints as Assert;
      
      public function getParameters(): array
      {
          return [
              'date' => [
                  'value' => $request->query->get('date'),
                  'constraints' => [new Assert\DateTime()],
              ],
          ];
      }
      
  4. Route Conflicts

    • Default routes (/report/{name}) may clash with existing routes.
    • Fix: Override routes in config/routes.yaml:
      bisonlab_reports:
          resource: "@BisonLabReportsBundle/Resources/config/routes.xml"
          prefix: "/custom_prefix"
      

Debugging Tips

  • Check Registered Reports:
    php bin/console debug:container bisonlab.reports.report
    
  • Log Report Generation: Enable debug mode in bisonlab_reports.yaml:
    bisonlab_reports:
        debug: true
    
    Logs will appear in var/log/dev.log.

Extension Points

  1. Custom Storage Override storage engine (e.g., for database-backed reports):

    // src/Storage/CustomReportStorage.php
    class CustomReportStorage implements ReportStorageInterface
    {
        public function save(ReportInterface $report): void
        {
            // Custom logic (e.g., save to DB)
        }
    }
    

    Register in services.yaml:

    BisonLab\ReportsBundle\Storage\ReportStorageInterface: '@App\Storage\CustomReportStorage'
    
  2. Event Listeners Hook into report lifecycle:

    // src/EventListener/ReportListener.php
    class ReportListener implements EventSubscriberInterface
    {
        public static function getSubscribedEvents(): array
        {
            return [
                ReportEvents::PRE_GENERATE => 'onPreGenerate',
            ];
        }
    
        public function onPreGenerate(ReportEvent $event): void
        {
            // Modify $event->getReport() before generation
        }
    }
    
  3. Security Restrict report access:

    // src/Security/Voter/ReportVoter.php
    class ReportVoter extends Voter
    {
        protected function supports(string $attribute, $subject): bool
        {
            return $attribute === 'VIEW_REPORT' && $subject instanceof ReportInterface;
        }
    
        protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
        {
            return $token->getUser()->hasRole('ROLE_REPORT_USER');
        }
    }
    

    Secure routes in ReportController:

    public function indexAction(string $name, Request $request)
    {
        $this->denyAccessUnlessGranted('VIEW_REPORT', $this->getReport($name));
        return $this->renderReport($name, $request->query->all());
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours