Zend Framework Farklı Modüller aynı Modelleri Nasıl Kullanılır?

5 Cevap php

Ben bir kamu pazarlama alanı, özel üye alanı, yönetim sitesine, ve bir pazarlama kampanyası yönetimi sitesine sahip varolan bir proje içinde Zend Framework uygulama üzerinde çalışıyorum. Şu anda bu kötü pazarlama alanı için denetleyici komut ve üye alanı tüm sitenin kök altında olması ve daha sonra yönetici ve pazarlama kampanyası site için başka bir klasör için ayrı bir klasör ile organize edilmektedir.

Zend Framework uygulanmasında, ben modüllere (üye alanı için bir tane, kamu pazarlama alanı için bir tane, admin site için bir tane, ve pazarlama kampanyası admin site için bir tane) denetleyicileri ve görüşlerini bölmek edebilmek oluşturmak istiyorum ama tüm üç bileşen aynı veritabanı üzerinde ve aynı iş nesneleri üzerinde çalışmak beri aynı model in her modül işaret etmek gerekiyor.

Ancak, belgelerde bu yapmak konusunda herhangi bir bilgi bulmak mümkün olmamıştır. Herkes bunu yapmak için nasıl bir bağlantı veya bunu gerçekleştirmek için bazı basit talimatlar ya yardımcı olabilir misiniz?

5 Cevap

Ne yapmam modülleri hiyerarşi dışında bir "kütüphane" dizininde ortak sınıfları tutmak. Sonra set benim INCLUDE_PATH, ilgili modülün "modeller" dizini, artı ortak "kütüphane" dizini kullanmak için.

docroot/
    index.php
application/
    library/    <-- common classes go here
    default/
        controllers/
        models/
        views/
    members/
        controllers/
        models/
        views/
    admin/
        controllers/
        models/
        views/
. . .

Benim önyükleme komut, ben INCLUDE_PATH için "application/library/" eklemek istiyorum. Sonra her Kontrolörün init() fonksiyonu, ben INCLUDE_PATH bu modülün "models/" dizin eklemek istiyorum.

edit: setControllerDirectory() ve setModuleDirectory() INCLUDE_PATH için ilgili modeller dizinleri katmayan gibi fonksiyonlar. Herhangi bir durumda, bu kendiniz yapmak zorunda. İşte bunu yapmak için nasıl bir örnek:

$app = APPLICATION_HOME; // you should define this in your bootstrap
$d = DIRECTORY_SEPARATOR;
$module = $this->_request->getModuleName(); // available after routing
set_include_path(
  join(PATH_SEPARATOR,
    array(
      "$app{$d}library",
      "$app{$d}$module{$d}models",
      get_include_path()
    )
  )
);

Modül bağlıdır, çünkü bootstrap içinde yoluna "library" ekleyebilirsiniz, ancak bootstrap doğru modülü için "models" dizin ekleyemezsiniz yönlendirme. Bazı insanlar kendi kontrolörleri init() yönteminde bunu, ve bazı insanlar INCLUDE_PATH ayarlamak için ActionController en preDispatch kanca için bir eklenti yazmak.

Bu aynı zamanda Zend_Loader takip için bir adlandırma kuralı yoluyla gerçekleştirilebilir. Onların modül klasörünün altındaki modeller klasörüne modeli dosyaları tutun. Module_Models_ModelName olarak isim ve o modül için modeller klasörde bir dosya adı ModelName.php bunları kaydedin. Uygulama klasör senin yolunu ve Zend_Loader otomatik yükleme için kullandığınız varsayarak dahil olduğundan emin olun, daha sonra sadece kendi sınıf adıyla modelleri başvuruda bulunabilir.

Bu, bunun için olan gerçek modülü ile gruplanmış da model kodunu tutma avantajına sahiptir. Bu encapsulation teşvik yardımcı olur, tek bir klasör yapısı içinde bulunan modülü tutar. Eğer bağlantı noktasına başka bir proje için modülü gerekiyorsa bu da gelecekte yardımcı olacaktır.

Ben sadece tarif sorun için bu özel Eylem Yardımcı yili:

<?php

class My_Controller_Action_Helper_GetModel extends Zend_Controller_Action_Helper_Abstract
{
  /**
   * @var Zend_Loader_PluginLoader
   */
  protected $_loader;

  /**
   * Initialize plugin loader for models
   * 
   * @return void
   */
  public function __construct()
  {
    // Get all models across all modules
    $front = Zend_Controller_Front::getInstance();
    $curModule = $front->getRequest()->getModuleName();

    // Get all module names, move default and current module to
    //  back of the list so their models get precedence
    $modules = array_diff(
      array_keys($front->getDispatcher()->getControllerDirectory()),
      array('default', $curModule)
    );
    $modules[] = 'default';
    if ($curModule != 'default') {
      $modules[] = $curModule;
    }

    // Generate namespaces and paths for plugin loader
    $pluginPaths = array();
    foreach($modules as $module) {
      $pluginPaths[ucwords($module)] = $front->getModuleDirectory($module) . '/models';
    }

    // Load paths
    $this->_loader = new Zend_Loader_PluginLoader($pluginPaths);
  }

  /**
   * Load a model class and return an object instance
   * 
   * @param  string $model 
   * @return object
   */
  public function getModel($model)
  {
    $class = $this->_loader->load($model);
    return new $class;
  }

  /**
   * Proxy to getModel()
   * 
   * @param  string $model 
   * @return object
   */
  public function direct($model)
  {
    return $this->getModel($model);
  }
}

Lütfen bootstrap.php Yani:

Zend_Controller_Action_HelperBroker::addPrefix('My_Controller_Action_Helper');

Ve denetleyicileri herhangi:

<?php

class IndexController extends Zend_Controller_Action 
{
  public function indexAction() 
  {
    $model = $this->_helper->getModel('SomeModel');
  }
}

Ve bu tüm modüller arasında herhangi bir kontrol modelleri için erişim sağlayacaktır.

I'm having the same problem. Bill's answer doesn't fit for me - cos i tend to divide my modules, not by 'who is seeing them', but by 'what they do'. E.g a 'forum module' might be managed by both admin and public. I'm trying to have front end modules, like admin, members , public - but these then use other modules like 'forum/validatepost', 'forum/show users personal info'. If anyone could shed light on how they protect a back-end module from the public , then that would be handy. I guess ACL may be the key but it still makes me nervous having access controlled by objects as opposed 'file system/.htaccess' etc.

To answer PHPoet's question : (i) Paths to module's controller directories can be specified by calls to front controller: e.g see : "12.11.2. Specifying Module Controller Directories" (Zend Framework Docs)

(ii) Paths to views can be set using ViewRenderer (Controller Action Helper) e.g. see: 'Example 12.12. Choosing a Different View Script' (Zend Framework Docs)

Böylece, normal olarak çalıştırmak için autoloader boşaltarak, görüş ve denetleyicileri için varsayılan yolları değiştirmek olası uğraşırken.

(Ben yolu autoloader işlerin içine bakmadım, ama sorun bu tür çözmek için bazı mapper sistemine sahip olmak için mantıklı olur.)

<?php
return array(
'modules' => array(
    'Application',
    'DoctrineModule',
    'DoctrineORMModule',
    'Merchant',
),
'module_listener_options' => array(
    'config_glob_paths'    => array(
        'config/autoload/{,*.}{global,local}.php',
    ),
    'module_paths' => array(
        './module',
        '../vendor',
//            'here we can load module'
        'comomonmodule'   

    ),
),
);