2008-11-03 23 views
8

Estoy trabajando en la implementación de Zend Framework dentro de un proyecto existente que tiene un área de marketing público, un área de miembros privados, un sitio de administración y un sitio de administración de campañas de marketing. Actualmente estos están mal organizados con las secuencias de comandos del controlador para el área de marketing y los miembros están todos bajo el directorio raíz del sitio y luego una carpeta separada para el administrador y otra carpeta para el sitio de la campaña de marketing.¿Cómo usar los mismos modelos en diferentes módulos en Zend Framework?

Al implementar Zend Framework, me gustaría crear poder dividir los controladores y vistas en módulos (uno para el área de miembros, uno para el área de marketing público, uno para el sitio de administración y otro para el marketing sitio de administración de campaña), pero necesito poder señalar cada módulo con el mismo modelo, ya que los tres componentes funcionan en la misma base de datos y en los mismos objetos comerciales.

Sin embargo, no he podido encontrar ninguna información sobre cómo hacer esto en la documentación. ¿Alguien puede ayudar con un enlace sobre cómo hacer esto o con algunas instrucciones simples sobre cómo lograrlo?

Respuesta

9

Lo que hago es mantener las clases comunes en un directorio de "biblioteca" fuera de la jerarquía de módulos. Luego configure mi INCLUDE_PATH para usar el directorio "modelos" del módulo respectivo, más el directorio "biblioteca" común.

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

En mi proceso de arranque, yo añadiría "application/library/" al INCLUDE_PATH. Luego, en la función init() de cada controlador, agregaría el directorio "models/" de ese módulo al INCLUDE_PATH.

edición: Funciones como setControllerDirectory() y setModuleDirectory() no añaden los directorios respectivos modelos a la INCLUDE_PATH. Tienes que hacer esto tú mismo en cualquier caso. Aquí está un ejemplo de cómo hacerlo:

$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() 
    ) 
) 
); 

podría añadir el "library" a su trayectoria en el arranque, pero no se puede añadir el directorio "models" para el módulo correcto en el arranque, porque el módulo depende del enrutamiento. Algunas personas hacen esto en el método init() de sus controladores, y algunas personas escriben un complemento para el gancho preDispatch del ActionController para configurar el INCLUDE_PATH.

+0

¿Hay alguna razón por la que no se utiliza addControllerDirectory() en lugar de añadir un valor a la include_path? –

+0

addControllerDirectory() no agrega el directorio de modelos respectivos a su ruta de inclusión, hasta donde yo sé. Ver ejemplos en mi edición anterior. –

3

Esto también se puede lograr a través de una convención de nombres para seguir Zend_Loader. Mantenga sus archivos de modelo en la carpeta de modelos debajo de su carpeta de módulo. Llámelos como Module_Models_ModelName y guárdelos en un nombre de archivo ModelName.php en la carpeta de modelos para ese módulo. Asegúrese de que la carpeta de la aplicación se encuentre en su ruta de inclusión y suponiendo que está utilizando Zend_Loader para cargar automáticamente, puede simplemente hacer referencia a los modelos por su nombre de clase.

Esto tiene la ventaja de mantener el código del modelo agrupado con el módulo real para el que está. Esto mantiene el módulo dentro de una estructura de carpetas única que ayuda a fomentar la encapsulación. Esto también ayudará en el futuro si necesita transferir el módulo a otro proyecto.

0

Estoy teniendo el mismo problema. La respuesta de Bill no encaja para mí, porque tiendo a dividir mis módulos, no por 'quién los está viendo', sino por 'lo que hacen'. Por ejemplo, un 'módulo de foro' podría ser administrado tanto por el administrador como por el público. Estoy tratando de tener módulos frontales, como administradores, miembros, públicos, pero estos luego usan otros módulos como 'forum/validatepost', 'forum/show users personal information'. Si alguien pudiera arrojar luz sobre cómo protegen un módulo de fondo del público, sería útil. Supongo que ACL puede ser la clave, pero todavía me pone nervioso tener acceso controlado por objetos en lugar de 'file system/.htaccess', etc.

Para responder la pregunta de PHPoet: (i) Se pueden especificar rutas a los directorios del controlador del módulo mediante llamadas a controlador frontal: por ejemplo, véase: "12.11.2 Especificación de módulo controlador directorios" (Zend Framework Docs)

(ii) Caminos hacia vistas se pueden establecer utilizando ViewRenderer (controlador de ayudante de acciones) por ejemplo, ver: 'Ejemplo 12.12. Elección de una secuencia de comandos de visualización diferente (Zend Framework Docs)

Al jugar es posible alterar las rutas de acceso predeterminadas a las vistas y los controladores, lo que libera el autocargador para que se ejecute normalmente.

(no he mirado en la forma en que funciona cargador automático, sino que tendría sentido para que tenga algún sistema asignador de resolver este tipo de problema.)

1

Acabo de construir esta costumbre ayudante de acciones por el problema describir:

<?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); 
    } 
} 

Así que en su Bootstrap.php:

Zend_Controller_Action_HelperBroker::addPrefix('My_Controller_Action_Helper'); 

Y en cualquiera de sus controladores:

<?php 

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

Y esto le permitirá el acceso a los modelos en cualquier controlador en todos los módulos.

0

<?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' 

    ), 
), 
); 
Cuestiones relacionadas