简体   繁体   中英

Symfony add bundle and have my 'CoreBundle' realise it

I currently have Test\\CoreBundle which is intend on containing basic functions to get my website online (eg a splash page and basic admin panel).

What I want to do is be able to drop in Test\\UserBundle and have the CoreBundle realise that I've added a new bundle so it can include this in the administrator panel. I thought I might be able to do something like:

In my Test\\UserBundle I add a config.yml file such as:

include_admin:
    directory: "users"
    name: "User Management"

(i'd then add the bundle it to the AppKernel.php)

In my admin panel index:

$bundles = $this->container->getParameter('kernel.bundles');
foreach($bundles as $bundle){
  if(strpos($bundle,'Test') !== false){
    // access the config.yml file somehow for this bundle?
  }
}

I'd then be able to do something like this in my view:

<a href="/admin/{{ directory }}">{{ name }}</a>

I don't know if I'm going about this completely cack-handedly due to not knowing anything about sf.

You can create a listener in CoreBundle that would listen for other Bundle's "participation". I've done something similar below to build a navigation based on menu items for any bundles I wish. You can modify the events & event listeners below to pass whatever data you need.

Basically, you create an Event & Event Listener in CoreBundle, and have each other independent bundle register the EventListener whenever the CoreBundle dispatches an event.

For example, in your CoreBundle, create an event:

use Symfony\Component\EventDispatcher\Event;

class BundleEvent extends Event
{
    const EVENT = "core.bundle.find_bundles";

    private $bundles;

    public function addBundle($bundle)
    { 
         $this->bundles[] = $bundle;
    }

    public function getBundles()
    {
         return $this->bundles;
    }
}

Then create an event listener in your CoreBundle:

use Acme\CoreBundle\BundleEvent;

class BundleListener
{ 
    private $bundle_path;

    public function __construct($bundle_path)
    { 
         $this->bundle_path= $bundle_path;
    }

    public function addBundle(BundleEvent $event)
    {
         $event->addBundle($this->bundle_path);
    }
}

Then, in each of your Bundle's services.xml that you want CoreBundle to be aware of, use this:

<service id="acme.user.bundle_listener" class="Acme\CoreBundle\BundleListener">
    <argument>Acme\UserBundle</argument>
    <tag name="kernel.event_listener" event="core.bundle.find_bundles" method="addBundle" />
</service>

Finally, in your CoreBundle (or wherever else you need to get this list), when you want to get all of the bundles you are looking for, run the event through the event dispatcher:

$bundles = $this->container->get('event_dispatcher')->dispatch(BundleEvent::EVENT, new BundleEvent())->getBundles();

foreach($bundles as $bundle_path) {
    // .. do something
}

If someone else has a simpler way of accomplishing this, I'd love to know an easier/cleaner way!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM