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));
Related
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'
));
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'm trying to test a controller. Zend Tool has generated the following code:
class Default_CarrinhoControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
public function setUp()
{
$this->bootstrap = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
parent::setUp();
}
public function testIndexAction()
{
$params = array('action' => 'index', 'controller' => 'Carrinho', 'module' => 'default');
$urlParams = $this->urlizeOptions($params);
$url = $this->url($urlParams);
$this->dispatch($url);
// assertions
$this->assertModule($urlParams['module']);
$this->assertController($urlParams['controller']);
$this->assertAction($urlParams['action']);
$this->assertQueryContentContains(
'div#view-content p',
'View script for controller <b>' . $params['controller'] . '</b> and script/action name <b>' . $params['action'] . '</b>'
);
}
}
PHPUnit Bootstrap
<?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();
// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
But it has failed and route is correct
Default_CarrinhoControllerTest::testIndexAction()
Zend_Controller_Router_Exception: Route default is not defined
C:\xampp\ZendFramework-1.11.11\library\Zend\Controller\Router\Rewrite.php:318
C:\xampp\ZendFramework-1.11.11\library\Zend\Controller\Router\Rewrite.php:469
C:\xampp\ZendFramework-1.11.11\library\Zend\Test\PHPUnit\ControllerTestCase.php:1180
C:\htdocs\farmaciaonline\FarmaciaOnlineWeb\tests\application\modules\default\controllers\CarrinhoControllerTest.php:16
C:\xampp\php\PEAR\PHPUnit\Framework\TestCase.php:939
C:\xampp\php\PEAR\PHPUnit\Framework\TestCase.php:801
C:\xampp\php\PEAR\PHPUnit\Framework\TestResult.php:649
C:\xampp\php\PEAR\PHPUnit\Framework\TestCase.php:748
C:\xampp\php\PEAR\PHPUnit\Framework\TestSuite.php:772
C:\xampp\php\PEAR\PHPUnit\Framework\TestSuite.php:745
C:\xampp\php\PEAR\PHPUnit\Framework\TestSuite.php:705
C:\xampp\php\PEAR\PHPUnit\TextUI\TestRunner.php:325
C:\xampp\php\PEAR\PHPUnit\TextUI\Command.php:187
C:\xampp\php\PEAR\PHPUnit\TextUI\Command.php:125
C:\xampp\php\phpunit:44
I have the default phpunit generated bootstrap by zend tool, I've setted up some custom routes but the default routes are still working on the application. What could be wrong?
Looks like there's an issue with the the Controller Test Case not setting the default route, if custom routes have been set (this is a different behavior than the framework).
The patch from the issue:
/**
* URL Helper
*
* #param array $urlOptions
* #param string $name
* #param bool $reset
* #param bool $encode
*/
public function url($urlOptions = array(), $name = null, $reset = false, $encode = true, $default = false)
{
$frontController = $this->getFrontController();
$router = $frontController->getRouter();
if (!$router instanceof Zend_Controller_Router_Rewrite) {
throw new Exception('This url helper utility function only works when the router is of type Zend_Controller_Router_Rewrite');
}
if ($default) {
$router->addDefaultRoutes();
}
return $router->assemble($urlOptions, $name, $reset, $encode);
}
You'll need to pass true as the last argument when using the url() function.
Instead of patching the Test Case, you can just add the default routes someplace in the bootstrap process:
$frontController->getRouter()->addDefaultRoutes();
This sounds like a typical problem you have not configured your app in the bootstrap properly and then invoking a request which leads to an undefined route. In your case the route is specified as Route default.
The route might be correct but just undefined.
For debugging purposes, output the $url you invoke so you see what's going on.
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)