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

Perfil Bundle Laravel Package

ascensodigital/perfil-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require ascensodigital/perfil-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        AscensoDigital\PerfilBundle\AscensoDigitalPerfilBundle::class => ['all' => true],
    ];
    
  2. Database Migrations: Run migrations to create the required tables (e.g., perfil, perfil_navegacion, perfil_reporte):

    php bin/console doctrine:migrations:diff
    php bin/console doctrine:migrations:migrate
    
  3. First Use Case:

    • Define a profile (e.g., Admin, User, Guest) in the database via Perfil entity.
    • Assign navigation items (e.g., menus, links) to profiles using the PerfilNavegacion entity.
    • Assign reports (e.g., PDF exports, charts) to profiles via PerfilReporte.

    Example CRUD via CLI:

    php bin/console make:entity PerfilNavegacion --fields="name:string,url:string,perfil:many-to-one"
    php bin/console make:entity PerfilReporte --fields="name:string,type:string,perfil:many-to-one"
    

Implementation Patterns

Core Workflows

  1. Profile-Based Navigation:

    • Use the PerfilNavegacion entity to dynamically render menus in templates (e.g., Twig):
      {% for item in perfil_navegacion_list %}
          <a href="{{ item.url }}">{{ item.name }}</a>
      {% endfor %}
      
    • Fetch navigation items for the current user’s profile in a controller:
      $profile = $this->getUser()->getPerfil(); // Assuming User extends UserBundle's User
      $navItems = $profile->getNavegacions();   // Via Doctrine relations
      
  2. Report Access Control:

    • Integrate with PerfilReporte to gate report endpoints:
      public function generateReportAction(PerfilReporte $report)
      {
          $userProfile = $this->getUser()->getPerfil();
          if (!$userProfile->hasReporte($report)) {
              throw $this->createAccessDeniedException();
          }
          // Generate report logic...
      }
      
  3. EasyAdmin Integration:

    • Extend EasyAdmin’s CRUD controllers to filter profiles:
      use AscensoDigital\PerfilBundle\Entity\Perfil;
      
      class PerfilCrudController extends EasyAdminCrudController
      {
          public function configureFields(string $pageName): iterable
          {
              return [
                  Field::new('name'),
                  Field::new('description')->onlyOnIndex(),
                  AssociationField::new('navegacions'),
                  AssociationField::new('reportes'),
              ];
          }
      }
      
  4. Slug-Based Routing:

    • Use cocur/slugify for SEO-friendly profile URLs:
      $profile = $this->getDoctrine()->getRepository(Perfil::class)->findOneBy(['slug' => $slug]);
      

Integration Tips

  • UserBundle Sync: Link UserBundle's User entity to Perfil via a many-to-one relation:

    // src/Entity/User.php
    /**
     * @ORM\ManyToOne(targetEntity="AscensoDigital\PerfilBundle\Entity\Perfil")
     */
    private $perfil;
    

    Override loadUserByUsername to hydrate the profile:

    public function loadUserByUsername($username)
    {
        $user = parent::loadUserByUsername($username);
        $user->setPerfil($this->getDoctrine()->getRepository(Perfil::class)->findOneBy(['user' => $user]));
        return $user;
    }
    
  • Event Listeners: Trigger actions on profile changes (e.g., clear cache for navigation):

    // src/EventListener/PerfilListener.php
    class PerfilListener implements EventSubscriberInterface
    {
        public static function getSubscribedEvents()
        {
            return [
                KernelEvents::VIEW => ['onKernelView'],
            ];
        }
    
        public function onKernelView(GetResponseForControllerResultEvent $event)
        {
            $profile = $this->getUser()->getPerfil();
            $event->getControllerResult()->setData(['nav_items' => $profile->getNavegacions()]);
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Deprecated Dependencies:

    • The bundle requires EasyAdminBundle v1.17 and Symfony 3.x/4.x (last release: 2016).
    • Workaround: Use a wrapper or fork for modern Symfony (e.g., easycorp/easyadmin-bundle:^3.4).
    • Risk: Security vulnerabilities in outdated packages (e.g., friendsofsymfony/user-bundle).
  2. Missing Doctrine Relations:

    • The Perfil, PerfilNavegacion, and PerfilReporte entities may lack proper Doctrine mappings in the source.
    • Fix: Manually define relations in your Perfil entity:
      /**
       * @ORM\OneToMany(targetEntity="AscensoDigital\PerfilBundle\Entity\PerfilNavegacion", mappedBy="perfil")
       */
      private $navegacions;
      
  3. Hardcoded EasyAdmin Routes:

    • The bundle assumes EasyAdmin is installed. If not, navigation/report routes will 404.
    • Solution: Override routing in config/routes.yaml or use a feature flag.
  4. No Built-in ACL:

    • The bundle lacks granular permissions (e.g., "edit navigation item").
    • Tip: Combine with sonata-project/admin-bundle or symfony/security for fine-grained control.

Debugging

  • Dump Profile Data:
    dump($this->getUser()->getPerfil()->getNavegacions()->map(fn($item) => $item->getUrl()));
    
  • Check Fixtures: The bundle includes doctrine/doctrine-fixtures-bundle. Load sample data with:
    php bin/console doctrine:fixtures:load
    

Extension Points

  1. Custom Report Types: Extend PerfilReporte to support new report formats (e.g., CSV, Excel):

    // src/Entity/CustomPerfilReporte.php
    class CustomPerfilReporte extends PerfilReporte
    {
        private $format; // e.g., 'xlsx'
    
        // Add getters/setters and override generate() logic.
    }
    
  2. Dynamic Navigation: Use Twig extensions to filter navigation items dynamically:

    {% set activeNav = perfil_navegacion_list|filter((item) => item.url == app.request.uri) %}
    
  3. Profile Inheritance: Implement a ProfileHierarchy trait to allow profiles to inherit navigation/reports:

    trait ProfileHierarchy
    {
        public function getAllNavegacions(): Collection
        {
            return $this->navegacions->merge($this->parent?->getAllNavegacions());
        }
    }
    

Configuration Quirks

  • Bundle Prefix: The bundle uses ascenso_digital_perfil as a default namespace prefix. Override in config/packages/ascenso_digital_perfil.yaml if needed.
  • Translation: No built-in translation support. Manually add translations for PerfilNavegacion labels in translations/messages.en.yaml:
    navigation:
        name: "Navigation Item"
    

Performance

  • Eager-Load Relations: Avoid N+1 queries when fetching profiles:
    $profile = $this->getDoctrine()
        ->getRepository(Perfil::class)
        ->find($id, ['navegacions' => 'join', 'reportes' => 'join']);
    
  • Cache Navigation: Cache rendered navigation in a fragment or Varnish for high-traffic sites.

```markdown
---
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.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle