Sorry for my English, but please help me. How can i find model in modules. I used Zend Framework 1.12 and i run php file in command line. Example code:
//file located in project/scripts/test.php
<?php
//ini_set("display_errors","1"); ini_set("error_reporting", E_ALL);
// Initialize the application path and autoloading
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', $argv[1]);
set_include_path(implode(PATH_SEPARATOR, array(
APPLICATION_PATH . '/../library',
get_include_path(),
)));
require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();
// Initialize Zend_Application
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
//this model i can find
$sendQueueModel = new Application_Model_DbTable_SendQueue();
//but this i can't. Managers - this is module in project
$managersMOdel = new Managers_Model_Company();
That module is not loading thats why you cant access models. In normal way we add autoloader in Bootstap.php, here you should try the same code to load it. (after initializing Zend_Application)
$autoLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Managers',
'basePath' => APPLICATION_PATH . '/modules/managers'
));
Related
I have Zend Framework command line application. All models and stuff that I use in this application are now in default module (Application prefix) but I want to move them to cli module. When I moved my model to application/cli/model folder and renamed class names then autoloader can't find them. I have also admin module and it is working fine.
Here is my server.php file:
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(__DIR__ . '/../application'));
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'development'));
require_once 'Zend/Application.php';
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
$application->getBootstrap()->bootstrap(array('date', 'config'));
and here is my application.ini:
[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
appnamespace = "Application"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 0
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
resources.modules[] = ""
What should I do to make modules work in command line mode?
I would guess you're missing the bootstrap file for your Cli module - it should live at application/modules/cli/Bootstrap.php. You might also need to ensure the module and front controller resources are initialized by adding them to your array, giving you:
$application->getBootstrap()->bootstrap(array('date', 'config', 'modules', 'frontController'));
If not we'll need more info, including the error you're getting, the class you are trying to use and where it is defined.
WHat you need is a cli entry point.
Normally you enter the app on index.php (or /) in your browser aka via http. This will normally build a response and a router. Because you are not comming via the web you have to tweak this a bit.
So create a file which you use as your entry point for example cli.php (copy it from public/index.php). And make some tweaks in it
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));
/** Zend_Application */
require_once 'Zend/Application.php';
// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
// bootstrap and retrieve the frontController resource
$front = $application->getBootstrap()
->bootstrap('frontController')
->getResource('frontController');
//Which part of the app we want to use?
$module = 'default'; //or other module
$controller = '<your controller>';
$action = '<your action>';
//create the request
$request = new Zend_Controller_Request_Simple ($action, $controller, $module, $options);
// set front controller options to make everything operational from CLI
$front->setRequest($request)
->setResponse(new Zend_Controller_Response_Cli())
->setRouter(new Custom_Controller_Router_Cli())
->throwExceptions(true);
// lets bootstrap our application and enjoy!
$application->bootstrap()
->run();
i got a problem regarding Unit-testing a Zend-Framework application under Ubuntu 12.04. The project-structure is a default zend application whereas the models are defined as the following
./application
./models
./DbTable
./ProjectStatus.php (Application_Model_DbTable_ProjectStatus)
./Mappers
./ProjectStatus.php (Application_Model_Mapper_ProjectStatus)
./ProjectStatus.php (Application_Model_ProjectStatus)
The Problem here is with the Zend-specific autoloading. The naming convention here appears that the folder Mappers loads all classes with _Mapper but not _Mappers. This is some internal Zend behavior which is fine so far.
On my windows machine the phpunit runs without any Problems, trying to initiate all those classes.
On my Ubuntu machine however with jenkins running on it, phpunit fails to find the appropriate classes giving me the following error
Fatal error: Class 'Application_Model_Mapper_ProjectStatus' not found
in /var/lib/jenkins/jobs/PAM/workspace/tests/application/models/Mapper/ProjectStatusTest.php
on line 39
The error appears to really be that the Zend-Autoloader doesn't load from the ubuntu machine, but i can't figure out how or why this works. The question remains of why this is. I think i've double checked every point of contact with the zend autoloading stuff, but i just can't figure this out. I'll paste the - from my point of view relevant snippets - and hope someone of you has any insight to this.
Jenkins Snippet for PHPUnit
<target name="phpunit" description="Run unit tests with PHPUnit">
<exec executable="phpunit" failonerror="true">
<arg line="--configuration '${basedir}/tests/phpunit.xml' --coverage-clover '${basedir}/build/logs/clover.xml' --coverage-html '${basedir}/build/coverage/.' --log-junit '${basedir}/build/logs/junit.xml'" />
</exec>
</target>
./tests/phpunit.xml
<phpunit bootstrap="./bootstrap.php">
... this shouldn't be of relevance ...
</phpunit>
./tests/bootstrap.php
<?php
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));
require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();
Any help will be appreciated.
I actually think the problem is with your "models/Mappers" folder. It should be "models/mappers" (all lowercase), and would explain why it works on Windows and not Linux.
As you can see from the Zend_Application_Module_Autoloader class:
$this->addResourceTypes(array(
'dbtable' => array(
'namespace' => 'Model_DbTable',
'path' => 'models/DbTable',
),
'mappers' => array(
'namespace' => 'Model_Mapper',
'path' => 'models/mappers',
),
However, as per my previous answer, I still believe you will need to bootstrap the application for all the default resources to be added automatically
From the ZF Manual:
Create a Model and Database Table
Before we get started, let's consider something: where will these classes live, and how will
we find them? The default project we created instantiates an
autoloader. We can attach other autoloaders to it so that it knows
where to find different classes. Typically, we want our various MVC
classes grouped under the same tree -- in this case, application/ --
and most often using a common prefix.
Zend_Controller_Front has a notion of "modules", which are individual
mini-applications. Modules mimic the directory structure that the zf
tool sets up under application/, and all classes inside them are
assumed to begin with a common prefix, the module name. application/
is itself a module -- the "default" or "application" module. As such,
we'll want to setup autoloading for resources within this directory.
Zend_Application_Module_Autoloader provides the functionality needed
to map the various resources under a module to the appropriate
directories, and provides a standard naming mechanism as well. An
instance of the class is created by default during initialization of
the bootstrap object; your application bootstrap will by default use
the module prefix "Application". As such, our models, forms, and table
classes will all begin with the class prefix "Application_".
Since Zend_Application_Module_Autoloader is loaded by default, you should only need to bootstrap your application (you don't have to run the front controller) as per the example at the of this answer.
If you don't want to bootstrap your application, you could short circuit the resource loading by initialising Zend_Application_Module_Autoloader yourself:
$autoloader = new Zend_Application_Module_Autoloader();
As you can see from the code, the __construct of this class calls initDefaultResourceTypes(), with all the goodies you are looking for:
class Zend_Application_Module_Autoloader extends Zend_Loader_Autoloader_Resource
{
/**
* Constructor
*
* #param array|Zend_Config $options
* #return void
*/
public function __construct($options)
{
parent::__construct($options);
$this->initDefaultResourceTypes();
}
/**
* Initialize default resource types for module resource classes
*
* #return void
*/
public function initDefaultResourceTypes()
{
$basePath = $this->getBasePath();
$this->addResourceTypes(array(
'dbtable' => array(
'namespace' => 'Model_DbTable',
'path' => 'models/DbTable',
),
'mappers' => array(
'namespace' => 'Model_Mapper',
'path' => 'models/mappers',
),
'form' => array(
'namespace' => 'Form',
'path' => 'forms',
),
'model' => array(
'namespace' => 'Model',
'path' => 'models',
),
'plugin' => array(
'namespace' => 'Plugin',
'path' => 'plugins',
),
'service' => array(
'namespace' => 'Service',
'path' => 'services',
),
'viewhelper' => array(
'namespace' => 'View_Helper',
'path' => 'views/helpers',
),
'viewfilter' => array(
'namespace' => 'View_Filter',
'path' => 'views/filters',
),
));
$this->setDefaultResourceType('model');
}
}
To only bootstrap your application without running the front controller in tests/bootstrap.php:
<?php
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));
require_once 'Zend/Loader/Autoloader.php';
$config = array(
APPLICATION_PATH . '/configs/application.ini'
);
// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
array('config' => $config)
);
$application->bootstrap();
Since the conventional Autoloader did not work, i tried to manually do what any Zend application would do. Here's the bootstrap.php that worked out in the end
<?php
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));
require_once 'Zend/Loader/Autoloader.php';
require_once 'Zend/Loader/Autoloader/Resource.php';
$resources = new Zend_Loader_Autoloader_Resource(array(
'namespace' => 'Application',
'basePath' => APPLICATION_PATH
));
$resources->addResourceType('form','forms','Form');
$resources->addResourceType('model','models','Model');
$resources->addResourceType('dbtable','models/DbTable','Model_DbTable');
$resources->addResourceType('mapper','models/Mappers','Model_Mapper');
The logic usually is what Zend should figure out on his own. And in fact it does so on my local development machine running on windows. On ubuntu however i need to become specific.
Would be interesting to know why that is. If someone can explain the reasoning to me, then I'll probably end up giving you the right answer ;)
I am hardly struggling against problem I experience for last two days.
In fact I can not run test properly and receive:
PHP Fatal error: Call to undefined function Zend_Application() in
C:\xxxxxx\tests\application\controllers\IndexControllerTest.php on
line 10
IndexControllerTest is very simple and looks like this:
require_once 'Zend/Test/PHPUnit/ControllerTestCase.php';
class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
public function setUp()
{
$this->bootstrap = Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
parent::setUp();
}
public function appBootstrap() {
$this->application = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
$this->application->bootstrap();
}
...
On the other hand bootstrap for tests contains only following code:
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); // /../application
// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));
require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();
Could you please help me with finding a problem? I would like to increase quality of mini project i indend to start but without testing it won't be possible.
Thank you in advance.
I added directories structure for my project. I keep zend libs in Source Files/library/Zend.
The error is coming from this:
$this->bootstrap = Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
You're missing a new before Zend_Application.
But, it's not clear to me what you have the appBootstrap function for unless you're going to use it:
public function setUp()
{
$this->appBootstrap();
parent::setUp();
}
What command are you using to run the tests?
If you don't load the bootstrap you'll get this error.
phpunit --bootstrap tests/bootstrap.php tests
I followed the steps in the following article in order to integrate Zend Framework 1.11 and Doctrine 2:
http://jeboy25.blogspot.com/2010/08/doctrine-2-and-zend-framework-110.html
And I have 3 questions about the article:
1-In the "SchemaToolClass" section i don't understand why the author includes schema_tool.php at the bottom of ZendProject/public/index.php file after :
$application->bootstrap()
->run();
2-when i execute the command "php doctrine orm:schema-tool:create" i have the following error message in the command line:
HP Stack trace:
PHP 1. {main}() /Library/WebServer/Documents/carlending/application/tools/doctrine:0
PHP 2. include() /Library/WebServer/Documents/carlending/application/tools/doctrine:7
PHP 3. require() /Library/WebServer/Documents/carlending/application/tools/doctrine.php:41
PHP 4. Doctrine\Common\ClassLoader->loadClass($className = uninitialized)
the error occurs in the cli-config.php file at the line '$config = new \Doctrine\ORM\Configuration();'
3-Can you explain why the author puts the doctrine generated proxies and models inside the domain folder. Isn't it better that they reside in the models folder like any other model class.
Sometimes i also see some programmers using a 'generated' folder inside models.
If you managed to make a working integration of Zend 1.x and Doctrine i would be very happy if you could also send me a working project that would very helpful.
Thanks for your help.
After reading "Obtaining the EntityManager" section in http://www.doctrine-project.org/docs/orm/2.1/en/tutorials/getting-started-xml-edition.html
I think you need the following three lines to bootstrap:
use Doctrine\ORM\Tools\Setup;
require_once 'Doctrine/ORM/Tools/Setup.php';
Setup::registerAutoloadPEAR();
I've got it to work a few weeks ago, here's my code. Doctrine 2 is really nice :)
In my bootstrap
/**
* Initialize auto loader of Doctrine
*
* #return Doctrine_Manager
*/
protected function _initDoctrine() {
$this->bootstrap('autoload');
require_once('Doctrine/Common/ClassLoader.php');
// Create the doctrine autoloader and remove it from the spl autoload stack (it adds itself)
require_once 'Doctrine/Common/ClassLoader.php';
$doctrineAutoloader = array(new \Doctrine\Common\ClassLoader(), 'loadClass');
//$doctrineAutoloader->register();
spl_autoload_unregister($doctrineAutoloader);
$autoloader = Zend_Loader_Autoloader::getInstance();
// Push the doctrine autoloader to load for the Doctrine\ namespace
$autoloader->pushAutoloader($doctrineAutoloader, 'Doctrine');
$classLoader = new \Doctrine\Common\ClassLoader('Entities', realpath(__DIR__ . '/models/'), 'loadClass');
$autoloader->pushAutoloader(array($classLoader, 'loadClass'), 'Entities');
$classLoader = new \Doctrine\Common\ClassLoader('Symfony', realpath(__DIR__ . '/../library/Doctrine/'), 'loadClass');
$autoloader->pushAutoloader(array($classLoader, 'loadClass'), 'Symfony');
$doctrineConfig = $this->getOption('doctrine');
$config = new \Doctrine\ORM\Configuration();
$cache = new \Doctrine\Common\Cache\ArrayCache;
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);
$driverImpl = new Doctrine\ORM\Mapping\Driver\YamlDriver(APPLICATION_PATH . '/../configs/mappings/yaml');
//$driverImpl = $config->newDefaultAnnotationDriver($doctrineConfig['path']['entities']);
$config->setMetadataDriverImpl($driverImpl);
$config->setProxyDir(APPLICATION_PATH . '/../proxies');
$config->setProxyNamespace('App\Proxies');
$connectionOptions = array(
'driver' => $doctrineConfig['conn']['driv'],
'user' => $doctrineConfig['conn']['user'],
'password' => $doctrineConfig['conn']['pass'],
'dbname' => $doctrineConfig['conn']['dbname'],
'host' => $doctrineConfig['conn']['host']
);
$registry = Zend_Registry::getInstance();
$registry->entitymanager = $em;
return $em;
}
Schema etc
I use yaml as you seen above, I haven't looked through the tutorial but I've used the command line tool that works like a charm, my doctrine.php (located in APPLICATION/bin):
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/..'));
// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'development'));
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path()
)));
/** Zend_Application */
require_once 'Zend/Application.php';
// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/../configs/application.ini'
);
$application->getBootstrap()->bootstrap('doctrine');
require_once __DIR__ . '/../Bootstrap.php';
$em = $application->getBootstrap()->getResource('doctrine');
$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em, APPLICATION_PATH . "/configs/mappings")
));
\Doctrine\ORM\Tools\Console\ConsoleRunner::run($helperSet);
You first have to generate your entities:
Generate all the models without deleting, creates also annotations -
./doctrine orm:generate-entities ~/Public/my_app/application/models/ --regenerate-entities 0 --generate-annotations 1
then generate your schema
./doctrine orm:schema-tool:create --dump-sql
or
./doctrine orm:schema-tool:update --dump-sql
the proxies are not really a part of your models, it's just used by Doctrine internally so I've put it as a separate entity from the models folder but I guess it doesn't really matter:
./doctrine orm:generate-proxies ~/Public/my_app/proxies/
Remember to add write permissions to the proxies for apache group.
Hmm... guess I didn't quite explain Jeboy's solution but perhaps my code helps you get started, it took me a while but once it's up and running it works like a charm :)
PS Don't forget the "namespace Entities;" in each of your models (it should be generated automatically)
i use zend framework 1.10 and i have a script under scripts library.
i run this script from command line.
how can i load all the models of doctrine and use them in my script.
in the begining of the script i write
/**
* Doctrine CLI script
*/
define('APPLICATION_ENV', 'production');
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
realpath(APPLICATION_PATH . '/../library/lib'),
realpath(APPLICATION_PATH . '/models/generated'),
realpath(APPLICATION_PATH .'/models'),
get_include_path()
)));
require_once 'Zend/Application.php';
// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
then i connect to doctrine
require_once 'Doctrine.php';
$doctrineConfig = $application->getOption('doctrine');
$manager = Doctrine_Manager::getInstance();
$manager->openConnection($doctrineConfig['connection_string']);
then when i try to run a query like :
$q = Doctrine_Query::create()
->select('c.CampaignId')
->from('ModelCampaigns c');
he write an error :
Fatal error: Uncaught exception
'Doctrine_Exception' with message
'Couldn't find class ModelCampaigns'
its ok now i add this to script :
require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->setFallbackAutoloader(true);
$moduleLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH));