Zend_Framework how to get the two URL Parameters - zend-framework

I have a build server (http://url.server.zip/release) which contains a list of zip files with some numeric numbers. E.g. http://url.server.zip/release/first_release_1,http://url.server.zip/release/first_release_2 and so on...
View: In my view page I have developed one search box from the search box, I need to search the string from that server (http://url.server.zip/release) then I have to display the release zip file in front view page.
public function viewPostAction() {
$this->params()->fromRoute('page', 1);
return new ViewModel();
}

I'm not sure I really understand your question, but I'll give a try.
Regardless of your situation, in general, you'll have to set the two parameters' name in the route (module.config.php). Like this for example where I want to get in the url the id and name of a theme :
'theme' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/theme/[:themeId]/[:themeName]',
...
The [] means that it is not mandatory to use a parameter in the link. Up to you to know if you want to make it mandatory or not.
The URL would be something like "http://test.com/12/testing". Then, you'll be able to get both of the parameters this way:
$themeId = $this->params()->fromRoute('themeId');
$themeName = $this->params()->fromRoute('themeName');
$themeId = 12 and $themeName = testing, if we follow the example.
Hope it is what you were looking for. If not, could you maybe give us some more info ? Like your routing file, etc.

Related

How to manage different versions of application by using plugins in cakephp 3?

I have a single cakephp 3 application
I have a generic view which render data depending of an array struture of fields configured in each Model, this array includes configurations for display each field in the view like (text titles, maxsize, sortable, etc..) and database configuration like (column name in the database/table, datatype, etc..) in the same array, and its working fine.
public $tableData = [
[
'name' => 'Table1.name',
'title' => 'Name',
'field' => 'name',
'sortable' => true,
'type' => 'string',
'size' => '50px',
],
[
'name' => 'Asosiation1.option',
'title' => 'Topic',
'field' => 'topic_option',
'sortable' => true,
'type' => 'string',
'size' => '150px',
],
... More fields and asosiations
]
But now, i need to have these same Models in different versions, because the structure of the database/table for each Model change every year, but i need to preserv/show the data corresponding to each version as it is.
So if a user request mySite.com/2010, Site must show data using Model array structure defined for that year especifically.
So, i created:
/plugins/Years/version2010
/plugins/Years/version2011
etc..
and in each pluging, I copied all Models changing only the namespace, defaultConnectionName (1 schema per Year) and array structure.
This provokes to have mutiple plugins loaded in bootstrap config.
Is there any way to load only the necesary plugin depending of the request ?(/2010, /2011, etc..)
Ex. In bootstrap.php I do for each plugin year:
Plugin::load('Years/version201X', ['bootstrap' => false, 'routes' => true]);
also
Is there any way to avoid having to specify the plugin name every time i do loadModel() or TableRegistry::get() ?
Ex. In main App GeneralController I have to do every time:
$this->loadModel('Years/version201X/Table1');
Or maybe there is another better approach to solve this situation i havent seen
Is there any way to load only the necesary plugin depending of the
request ?(/2010, /2011, etc.
Yes. Inside config/bootstrap.php you can check the request uri and then have a switch statement for the plugins. Something like this:
$uri = filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_SPECIAL_CHARS);
// might need explode('/', $uri); to extract the right URL component
switch ($uri) {
case '2011':
// load plugin
break;
case '2012':
// log plugin
break;
}
You probably dont even need the switch statement, be creative there. Obviously thats not exact, but if gives you the right idea.
Is there any way to avoid having to specify the plugin name every time
i do loadModel() or TableRegistry::get() ?
If the model is unique to the plugin then I am not sure how you get away with this. Whats the problem though? Just a few extra characters. Sounds like you only have to do this once per year, right? However, you might not have to specify that if you're within the scope of the plugin. I am not sure on that, but its worth trying.

Zend Translation and View Scripts

Form labels and error messages are translated automatically. But strings in the view scripts are not. I have to use $this->translate("text to transfer"); in each and every phtml files.I don't want to use this $this->translate("text to transfer"); method.How can I automatically translate view scripts as in the case of forms.My code is
protected function _initTranslation() {
$langNamespace = new Zend_Session_Namespace('language_sess');
$lang = $langNamespace->lang;
$registry = Zend_Registry::getInstance();
$tr = new Zend_Translate(
array(
'adapter' => 'array',
'content' => APPLICATION_PATH . "/languages/$lang/$lang.php",
'locale' => "ar",
'scan' => Zend_Translate::LOCALE_DIRECTORY
)
);
$registry->set('Zend_Translate', $tr);
return $registry;
}
OK, to make it clear, we need to understand few things:
Zend_Translate is supposed to translate only part of your site, not related to content. That is menu items, section names, titles, etc. You might have exceptions from that rule, especially if you use Zend_Translate_Adapter_Gettext.
For content, you should use something else to provide your translation. Usually, for example if it is a static article, you get that data from DB, not the language file.
In your case, if you are ok with a little bit "machine" translation, you should use google translate engine for sites
https://translate.google.com/manager/website/
As for dropping $this->translate("text to transfer"); part, you can try to translate all data in controller, but that is rather bad advice, I would advice you to do something else. When you pass your data to view, you can loop through it and make translation for each and everystring inside:
foreach($data as $key => $string) {
$data[$key] = $tr->translate($string);
}
or something like that. This is bad approach because of few reasons. But most important is that you are not dividing your presentation from your logic, and that is why the best place for this is View.
So my summary:
Try to keep using $this->translate()
If that really does not work for you, try to use google translate engine
If that is also not good for you, try Zend_Translate_Adapter_Gettext.
Please, do not use language files for your content.

TYPO3 new record appearing on wrong location in Backend List

I'm developing a new extension using ExtBase in TYPO3 (4.7) for a client.
I have however the strangest problem. In the back-end, my possible, new record types are - as usual - listed in the Insert new record Backend List. Usually each of these record-types are preceded by the module name (actually they are grouped right after the module name).. However, in my case, 1 or 2 of the record-types of any other extension appear within my extension's list as well.. I've been trying to figure out pretty much all that I can, I even copied the extension over to an entirely different TYPO3 installation, but the same problem persists..
If of any extension some records appear just below my extension's title, and I delete that particular extension, just some other record-types appear of another extension.
What's going on here??
Short & late answer:
i guess you have defined the title of your models in two different ways or with a non-existent languagefile in your ext_tables.php. Something like this:
Model1:
$TCA['tx_aaext_domain_model_one'] = array(
'ctrl' => array(
'title' => 'LLL:EXT:bn_news/Resources/Private/Language/locallang_db.xml:tx_bnnews_domain_model_categories',
Model2:
$TCA['tx_aaext_domain_model_two'] = array(
'ctrl' => array(
'title' => 'Static Title',
and/or your extension-name has an underscore like aa_extension, then this error can happen.
Make sure that both title-definitions are dynamic and begin with "LLL:EXT:" and point to an existing translation. Everything should be fine now.
Long answer will be to long :)

How can I access custom validators globally?

I created a my own validation class under /library/My/Validate/
In my form I have $this->addElementPrefixPath('My_Validate', 'My/Validate', 'validate');
I am using my validator like so:
$this->addElement('text', 'aField', array(
'validators' => array(
array('TestValidator', false, array('messages' => 'test failed')
),
));
This all works. However, I am interested in improving this in two ways.
I would like to make it so that all forms have access to my validator. Calling addElementPrefixPath() in every form doesn't seem to be a clean way of doing this.
I would like to pass in My_Validate_TestValidator instead of TestValidator so other developers know what they are working with right away.
To answer your first question, the only real easy way to do this would be to create your own instance of the form - My_Form_Abstract - which has an init() method that sets the prefix path - and then of course calls the parent init().
I'm not aware of a way to make your second method work flawlessly. You need to store a prefix in order to build the validator loader correctly. However, as an alternative, you might try creating new instances of the class using the full name, and then adding it to the element:
$element = $this->getElement('aField');
$myValidateTestValidator = new My_Validate_TestValidator();
$element->addValidator($myValidateTestValidator);

Correct routing for a Rest API with Zend

I'm trying to implement a REST API to my website.
My problem is that the default Zend routing gets in the way. I've first tried using Zend_Rest_Route but I haven't been able to understand how I was supposed to use it correctly for "deep" routes, aka website/api/resource1/filter/resource2/id.
Using the default Zend routing, I'd need to create a gigantic Resource1Controller to take care of all the possible actions, and I don't think it's the "good" way to do this.
I've tried using Resauce ( http://github.com/mikekelly/Resauce/), creating an api module and adding routes, but I'm not able to get it working correctly :
The patterns I added were :
$this->addResauceRoutes(array(
'api/resource' => 'resource',
'api/resource/:id' => 'custom',
'api/resource/filter' => 'resource-filter',
'api/resource/filter/:id' => 'custom',
));
Which then leads to this :
public function addResauceRoutes($routes) {
$router = Zend_Controller_Front::getInstance()->getRouter();
foreach ($routes as $pattern => $controller) {
$router->addRoute($controller,
new Zend_Controller_Router_Route($pattern, array(
'module' => 'api',
'controller' => $controller
)
)
);
}
Zend_Controller_Front::getInstance()->setRouter($router);
website/api/resource gets me the
Resource1Controller, ok
website/api/resource/filter gets me to the
resource1filterController, ok
website/api/resource/filter/:id gets me to
a custom controller, ok
I'd like for website/api/resource/:id to get me to the same custom controller... But it redirects me to the Resource1Controller.
What solution is there for me to correctly create my API ? Is there a good way to do this with Zend_Rest_Route ?
Edit : Mike,
I felt that it was not appropriate for me to use different controllers since I need the pathes "website/api/resource/:id" and "website/api/resource/filter/:id" to give me almost the exact same result (the only difference is that because the filter is there, I may get a message telling "content filtered" here).
I thought it was a waste creating another almost identical controller when I could've used the same controller and just checked if a parameter "filter" was present.
However, I don't want to use the basic Zend routing since for the path "website/api/resource/filter/resource2" I'd like to have a totally different comportment, so I'd like to use another controller, especially since I'm trying to use Zend_Rest_Action and need my controllers to use the basic actions getAction(), putAction(), postAction() and deleteAction().
Please could you explain why it is you need two URI patterns pointing to the same controller. A better solution might be to use a separate controller for each of the two patterns and move any shared logic into your model.
Forcing a unique controller for each routing pattern was an intentional design decision, so I'd be interested to hear more detail about your use case where you feel this isn't appropriate.
I thought it was a waste creating
another almost identical controller
when I could've used the same
controller and just checked if a
parameter "filter" was present.
Personally, I think it is cleaner to move the shared logic into the model and to keep your controllers skinny. To me it's not wasteful, it's just more organised - it will make your code easier to manage over time.
If you really need to use the same controller you could always use a query parameter instead, that would work fine:
api/resource/foo?filter=true
That URI would be taken care of by the first route ('api/resource/:id' => 'custom') for free.
But please consider using two controllers, I think that is a better approach.
Okay, the reason I didn't get the good controllers was because Resauce uses the controller name as the name of the route, which has to be unique - so second url pointing to "custom" controller couldn't work. Now I'm able to get the files I want :)
So instead of what was previously noted, I use directly the $router->addRoute(); and define new names each times, even if pointing to the same controller.
Example :
$router->addRoute('resource', new Zend_Controller_Router_Route('/api/resources/:id', array('module' => 'api', 'controller' => 'resource')));
$router->addRoute('resourceFiltered', new Zend_Controller_Router_Route('/api/resources/filter1/:id', array('module' => 'api', 'controller' => 'resource', 'filter' => 'filter1'));