I'm writing a new version of an API and would like to support legacy versions by having distinct sets of controllers for each version. Within the default "app\controllers" path in Lithium, I would like to have for example "v1" and "v2" paths.
I have tried accomplishing this within the route itself by doing something like:
Router::connect('/{:version}/{:controller}/{:action}{:args}', array(
'controller'=> '\app\controllers\{:version}\{:controller}Controller',
), array());
Then I tried overriding the path in the libraries bootstrap module by doing something like:
if( preg_match('/^\/(v[0-9\.]+)/', $_SERVER['REQUEST_URI'], $match) ) {
Libraries::paths(array(
'controllers' => "controllers\\".$match[1].'\\{:name}Controller',
'models' => "models\\".$match[1]."\\{:name}",
));
}
I spent about a half a day at work searching google and the very sparse lithium docs. I am not sure what release of Lithium we are using as I have stepped into this pre-existing code base.
Thanks for any tips you may have!
In your routes.php file, you should re-configure the Dispatcher default rules with
Dispatcher::config(array('rules' => array(
'v1' => array('controller' => 'app\controllers\v1\{:controller}Controller')
)));
and a continuation route to match /v1/... requests
Router::connect('/v1/{:args}', array('v1' => true), array(
'continue' => true, 'persist' => array('controller', 'v1')
));
You can easily use :version instead of a predefined version number if you need so.
Related
Using ZF2 to customise an Entity based on ZfcUser. Trying to use ScnSocialAuth and got a bit of a problem.
The problem is that I am using custom routes ('/account' instead of '/user') and when implementing ScnSocialAuth I cannot get the social code into my custom zfcuser view...?
I have \\view\zfc-user\user\register.php which overrides the zfcuser registration.
I have a customised route:
'account' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/account',
),
),
These are my zfc config modification within \my-module\config\module.config.php
'zfcuser' => array(
// telling ZfcUser to use our own class
'user_entity_class' => 'WMember\Entity\WMember',
// telling ZfcUserDoctrineORM to skip the entities it defines
'enable_default_entities' => false,
'table_name' => 'w_member',
'login_redirect_route' => 'account',
),
My global \config\application.config.php
'ScnSocialAuth',
'MyModule1',
'ZfcBase',
'ZfcUser',
'BjyAuthorize',
'GoalioMailService',
'GoalioForgotPassword',
'my-user-module',
Therefore, after all this:
I can see my own extended User registration form by navigating to
/account/register with no Social login links visible
I can see the ScnSocialAuth when navigating to /user/register
a) I cannot create the view in my module to override \vendor\scn-social-auth\user\register.phtml as was done with zfcuser
Please help with getting ScnSocialAuth to work with my custom route setup.
If this is just wrong please let me know as I'm not ZF2 expert. Happy to take 'constructive' criticism.
Saw these posts: How to (correctly) extend ScnSocialAuth\Authentication\Adapter\HybridAuth::authenticate() method?
and this as a result of the above post:
https://github.com/SocalNick/ScnSocialAuth/issues/202
NOTE: still running ZF-2.3* due to PHP 5.3,5.4
Instead of adding a custom route to your config, you need to over-ride the zfcuser route
<?php
// #file MyUserModule/config/module.config.php
return array(
// other config ...
'router' => array(
'routes' => array(
'zfcuser' => array(
'options' => array(
// this is the only change needed to route zfcuser to /account
'route' => '/account',
),
),
),
),
// more config ...
);
The ScnSocialAuth module uses the forward() plugin to render the content from zfcusers register view (and login view iirc), which means it will only ever look at the zfcuser route and completely ignore your custom route. The only way to have it use your custom route would be to replace ScnSocialAuths UserController with your own using identical code but forwarding to your custom route (much more work there, and still the potential to break anything else that expects zfcuser to be the route used)
Is it be possible to make a website that doesn't reveal any relative URL's at all?
Say for example, I have a domain name "somedomain.xyz" and I want to route everything through the default route, and I want not to reveal any paths or route structures to the end user.
The end user shall only see the domain name in the browser's address bar, like:
http://somedomain.xyz
or
https://somedomain.xyz.
Any path like
http://somedomain.xyz/index.php
or
http://somedomain.xyz/index or
http://somedomain.xyz/index/index
shall show a 404.
And I don't care about SEO stuff and static pages.
Is that possible with ZF2, and if yes, then how?
similar question: hide module and action name from zf2 routing
Just create a hostname route for subdomain.xyz like so:
'my-route' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'subdomain.xyz',
'defaults' => array(
'controller' => 'MyApp\Controller\TheController',
'action' => 'whatever-action',
),
),
),
see here for a complete solution, with using HTTP POST vars for the routing:
ZF2 routing via post vars
A plea for your indulgence. I have searched for answers and tried many things, so I now humbly turn here for help. It should be simple: I'm moving to CakePhp and I want to redirect my old query strings (action=show&id=2) to groovy cake URLs (/Feature/view/2).
I've tried this in the .htaccess file in the webroot:
RewriteCond %{QUERY_STRING} ^action=show&id=([0-9]+)$
RewriteRule /Features/view/%1? [R,L]
No love. I also tried:
RewriteRule action=show&id=([0-9]+) /Features/view/$1 [L]
No love.
I tried Cakephp's routes.php with:
Router::connect('index.php?action=show&id=([0-9]+)',array('controller' => 'features', 'action' => 'view', 'id' => $1));
But I've seen no evidence that regex can be used that way in routes.php so that was really just throwing up a prayer.
It's possible to do this. Right? Thanks for any advice!
I think you can do it within router.php!
Maybe, you can get away with:
Router::connect('?action=:action&id=:id',
array(
'controller' => 'myController',
'action' => 'myAction',
),
array(
'action' => '[a-zA-Z]+',
'id' => '[0-9]+',
)
);
Or (probably better) a series of more specific forms like:
Router::connect('?action=show&id=:id',
array(
'controller' => 'features',
'action' => 'view',
),
array(
'id' => '[0-9]+',
)
);
In this case, action and id would be available in $this->request->params in myController (and in the case of a standard like id, there might even be automagic to help!)
Though I'm not sure that the routing elements (:foo) will pick up GET params like that..
Alternatively, you could send everything to one controller anyway, and you should find the GET parameters are listed in $this->request->params['url'], so you can route everything in the controller (to other controllers, I guess).
Doesn't sound pretty either way, but I understand you want to keep some legacy urls running!
Iam new guy to Zend framework and currently Iam working on Zend2...I want to ask about Translator usage in Zend forms....If i want to use translator i directly using for labels in form view i.e.form_view.php like
$this->formLabel()->setTranslator($translator, 'date_of_birth');
But I want to add the translator at the form only i.e.in src/my_module/Form/UserForm.php
like
$this->add(array(
'name' => 'date_of_birth',
'attributes' => array(
'type' => 'text',
'id' => 'date_of_birth',
),
'options' => array(
'label' => 'DateOfBirth',
), //Here there is any option to put translator
));
Please help me...any answer would be help for me like I asked
Thanks in advance
You don't really need to do that. Since the the Translator that is set up using the factory-key translator will automatically be injected into the Form.
The best approach (in my opinion) is to make extensive use of the translator text_domain:
'translator' => array(
'locale' => 'de_DE',
'translation_file_patterns' => array(
array(
'type' => 'phparray',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.php',
'text_domain' => 'MyModuleTextDomain'
),
),
),
With this setup, the Files of your Module will automatically be inserted into the default TranslatorService which every Zend\Form knows of.
So ultimately all you have to do is make the ViewHelpers know of the TextDomain that you are using. And this is done in the following manner:
$this->formLabel()->setTranslatorTextDomain('MyModuleTextDomain');
$this->formButton()->setTranslatorTextDomain('MyModuleTextDomain');
$this->formElementErrors()->setTranslatorTextDomain('MyModuleTextDomain');
You need to do this once inside your respective view.phtml before(!) using the ViewHelpers like $this->formElement($element) or $this->formCollection($form)
And that's really all there is to it. I recall having seen a discussion somewhere about making it easier to pass along Text-Domain-Data, but i can't find it right now. So things may get a little easier in the future ;) For now, 3 lines are all that's needed though!
above answer is quite unnecessary ... as your translator was added automatically to zend form for rendering form labels and ....
only use this code in your module config :
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'phparray',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.php',
),
),
),
if u use the correct view helpers for rendering form elements (or whole form) it will automatically translated
This is not a recommended approach because forms are translated automatically if you have a translator configured (which you do if you are using the Skeleton Application). However, since you asked how to use the translator directly within your form, I will show you how you can do it. Please carefully consider if you really want to do this, as I cannot imagine a use case where it would be necessary.
To do exactly what you were asking, you can inject the translator into your form. You can do this either in your controller or in a factory. I will be using a factory in this example because it is more DRY.
// In your module's config file
'service_manager' => array(
'factories' => array(
'YourModule\Form\YourForm' => function($sm) {
$translator = $sm->get('Translator');
return new \YourModule\Form\YourForm($translator);
},
),
),
Then in your form class, you can do like this:
namespace YourModule\Form;
class RegisterForm extends \Zend\Form\Form {
public function __construct($translator) {
// Do something
$translated_string = $translator->translate('string to translate');
}
}
Then in your controller, you can do like this:
$your_form = $this->servicelocator->get('YourModule\Form\YourForm');
Or if you don't want to use the factory, you can choose to not add it and do like this instead:
$your_form = new \YourModule\Form\YourForm($this->servicelocator->get('Translator'));
I would recommend going with the factory, though.
I am trying to inject cache to a module using module.config.php with no luck. My module.config.php looks like this
return array(
'di' => array(
'instance' => array(
'AssetLoader\Module' => array(
'parameters' => array(
'cache' => 'Zend\Cache\Storage\Adapter\Filesystem',
),
),
),
),
);
and in my Module.php
public function setCache(\Zend\Cache\Storage\Adapter\Filesystem $cache)
{
die(__FUNCTION__);
$this->cache = $cache;
}
But nothing happens. I expect script to die but for some reason this function is never executed. I am sure I am doing something wrong but can someone explain how to inject a cache (or any other object in that matter) to the module?
This question is answered on Zend mailing list now.
See here
Matthew pointed out that Module classes weren't pulled out from locator, so you can't use DI to inject resources to the modules. See the link to see how it's done.