We can read here how to write:
http://framework.zend.com/manual/en/zend.validate.writing_validators.html
class MyValid_Float extends Zend_Validate_Abstract
{
1)
Where should we place this?
application/default/validators ?
application/view/helpers/... ?
2)
Do we have to register this somewhere on our application ?
Update:
Here's an example of my bootstrap:
include_once 'config_root.php';
set_include_path ( $PATH );
require_once 'Initializer.php';
require_once "Zend/Loader.php";
require_once 'Zend/Loader/Autoloader.php';
// Set up autoload.
$loader = Zend_Loader_Autoloader::getInstance ();
$loader->setFallbackAutoloader ( true );
$loader->suppressNotFoundWarnings ( false );
// Prepare the front controller.
$frontController = Zend_Controller_Front::getInstance ();
$frontController->throwExceptions(true);
$frontController->registerPlugin ( new Initializer ( PROJECT_ENV ) );
// Dispatch the request using the front controller.
try {
$frontController->dispatch ();
} catch ( Exception $exp ) {
$contentType = "text/html";
header ( "Content-Type: $contentType; charset=UTF-8" );
echo "an unexpected error occurred.";
echo "<h2>Unexpected Exception: " . $exp->getMessage () . "</h2><br /><pre>";
echo $exp->getTraceAsString ();
}
SO, do I have to add here:
$resourceLoader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => APPLICATION_PATH,
'namespace' => '',
));
$resourceLoader->addResourceType('validate', 'validators/', 'My_Validate_');
And then I should create a file IN: (note that this configuration is using default module):
application/default/validators/ValidateSpam.php
And on validateSpam.php have something like:
class My_Validate_Spam extends Zend_Validate_Abstract {
Can you please confirm ?
Thanks
Place your application/validators
then in your application's Bootstrap class, add the following function:
protected function _initAutoload () {
// configure new autoloader
$autoloader = new Zend_Application_Module_Autoloader (array ('namespace' => '', 'basePath' => APPLICATION_PATH));
// autoload validators definition
$autoloader->addResourceType ('Validator', 'validators', 'Validator_');
}
More detail(s) about Zend Bootstrap Autoloading.
Another way is described in this blog, where the constructor of the controller for the form that is using this custom validator has an extra line:
class JD_Form_Controller extends Zend_Form
{
public function __construct($options = null)
{
// path setting for custom classes MUST ALWAYS be first!
$this->addElementPrefixPath('JD_Form_Validator','JD/Form/Validator','validate');
...
}
...
}
I do it by adding the following line to application.ini :-
autoloadernamespaces[] = "App_"
Then I put my custom validators in (for example) /library/App/Validate/MyCustomValidator.php.
I can then write my validator using something like:-
class App_Validate_MyCustomValidator() extends Zend_Validate_Abstract
It works pretty well for me and is simple and easy to implement.
Related
I'm using Zend Framework 1.12. I know it's too old and that's why not finding much support so putting this question here.
I have CronController and I'm calling it through curl request and its not a good approach. As the name specifies, I want to call its functions through the command-line. Please suggest how can I achieve this.
I have tried implementing https://docs.zendframework.com/zend-console/intro/ but it didn't help much.
Thanks in advance.
I assume that CronController is class extending Zend_Controller_Action like this:
class CronController extends Zend_Controller_Action
{
public function processAction()
{
// some very important logic
}
}
If so, don't use this in your CLI calls. Zend_Controller_Action should be used rather with HTTP requests, not CLI calls.
Move your business logic from this controller to separate classes, i.e.:
class My_Logic
{
public function process($options)
{
// some very important logic
}
}
Then, following DRY principle, create instance of this class in your controller:
class CronController extends Zend_Controller_Action
{
public function processAction()
{
$logic = new My_Logic();
$logic->process();
}
}
Now, create bin directory in root path of your project and put there your CLI script (i.e. cron.php):
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
// 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();
$optsConfig = array(
'app_env=s' => 'Application environment name',
);
$opts = new Zend_Console_Getopt($optsConfig);
$opts->setOptions(
array(
'ignoreCase' => true,
'dashDash' => false,
)
);
$opts->parse();
defined('APPLICATION_ENV') || define('APPLICATION_ENV', $opts->app_env);
/** 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();
class CronCli
{
public function doProcessing()
{
$logic = new My_Logic();
// here's your logic, the same as in controller
$logic->process();
}
}
$cmd = new CronCli($opts);
$cmd->doProcessing();
Now, you can call this script in your project's main directory:
php bin/cron.php --app_env production
production is your APP_ENV value name from application/configs/application.ini
I have 1 zend (v1) application, and 2 module : default + admin
I want when call default module will be set router in configs/router/default.ini
and if in module admin do not any thing
I tried using plugin but it doesn't work
in my plugin
class Australian_Controller_Plugin_DefaultRouter extends Zend_Controller_Plugin_Abstract {
public function routeShutdown(Zend_Controller_Request_Abstract $request) {
$currModule = $request->getModuleName();
if ($currModule != 'default') {
return;
}
$fontController = Zend_Controller_Front::getInstance();
$router1 = new Zend_Controller_Router_Rewrite();
$fontController->getRouter()->removeDefaultRoutes();
$myRoutes = new Zend_Config_Ini(APPLICATION_PATH . '/configs/router/default.ini', 'production');
$router1->addConfig($myRoutes, 'routes');
$fontController->setRouter($router1);
}
}
and /default/Bootstrap.php
protected function _initRoutes() {
$fontController = Zend_Controller_Front::getInstance();
$fontController->registerPlugin(new Australian_Controller_Plugin_DefaultRouter());
}
thanks
Note that you are adding new router after Routing so Zend already decoded address using old routes. This way you can generate URLs using new routes, but they will not e recognized by Zend. You need to call $router->route($request); again to set module/controller/action using new set of routes.
Sadly this is not working when its called in routeShutdown and has to be added to preDispatch(). Sadly I'm quite new to Zend too and still not grasping why it is so.
Code i used:
$fontController = Zend_Controller_Front::getInstance();
$router = $fontController->getRouter();
$r = new Zend_Controller_Router_Route(
'/testnew',
array(
'module' => 'user',
'controller' => 'index',
'action' => 'myaccount',
));
$router->addRoute('testnew', $r);
$router->route($request);
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 am stuck in the follow situation. To check a url with zend_form, I have to add a custom validator. I try to add the custom validator named 'IsUrl.php' in;
What I do now
I add IsUrl.php to;
Library/Lib/Validate/
In my boodstrap:
protected function _initLibAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Lib',
'basePath' => dirname(__FILE__),
));
return $autoloader;
}
Test in Controller by;
$test = new Zend_Validate();
$test = new Lib_Validate_IsUrl();
Fatal error;
Fatal error: Class 'Lib_Validate_IsUrl' not found in
Thanks in advice.
With kind regards,
Nick
You will have to tell ZF, that you have custom validators :) You could adjust your bootstrap like this:
protected function _initValidators () {
$autoloader = new Zend_Application_Module_Autoloader (array ('namespace' => '', 'basePath' => APPLICATION_PATH));
$autoloader->addResourceType ('Validator', 'validators', 'Validator_');
}
I have custom front controller plugin that takes some options.
At this time I load it (plugin) in application.ini file like this:
resources.frontController.plugins.DynamicLayout = "My_Controller_Plugin_DynamicLayout"
At this time I just have option.ini file and then use zend_config to import it.
Is there a way to specify plugin options from ZEND's primary application.ini file?
Maybe something like this?:
resources.frontController.plugins.DynamicLayout.test = "test_value"
I use something like this to pass info to my layouts using bootstrap.
This example is for an application that runs on different domains, thus different layouts. (and has a separate version for MSIE). Each domain as a separate application.ini
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
protected function _initAutoload() {
return new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH
));
}
// <snip> more _initMethods: Loggers, ACLs, ViewHelpers, etc. </snip>
/**
* Setup dynamic layout plugin
*
* #return Zend_Controller_Plugin_Broker
*/
protected function _initFrontControllerLayoutPlugin() {
// Ensure the front controller is initialized
$this->bootstrap('FrontController');
$front = $this->getResource('FrontController');
$this->bootstrap('layout');
$layout = $this->getResource('layout');
// Set our Front Controller Plugin
// !!!! right here I pass values to the layout
// !!!! example layoutName, but you could pass anything you want...
$plugin = new Plugin_DynamicLayout($layout, $this->getOption('layoutName'));
return $front->registerPlugin($plugin);
}
}
The layout Handler:
<?php
class Plugin_DynamicLayout extends Zend_Controller_Plugin_Abstract {
private $layoutName;
public function __construct(Zend_Layout $layout, $layoutName) {
$this->layout = $layout;
$this->layoutName = $layoutName;
}
public function preDispatch(Zend_Controller_Request_Abstract $request) {
$layoutName = $this->layoutName;
if (false !== strpos($request->getHeader('User-Agent'), 'MSIE')) {
$layoutName = $layoutName . '-ie';
}
$this->layout->setLayout($layoutName);
}
}
The application.ini:
[production]
layoutName = "Some_File_Name"