Zend Framework paginator force $_GET params usage - zend-framework

Is it possible to use paginator with $_GET parameters?
For example i have a route like this:
$router->addRoute('ajax_gallery',
new Routes_Categories(
'/:lang/:category/age/:dep/:cat/:towns',
array(
"page" => 1,
"dep" => 0,
"cat" => 0,
"towns" => 0
),
array(
"dep" => "[0-9]+",
"cat" => "[0-9]+"
)
));
And i'm making request like this via ajax:
http://localhost/en/gallery?dep=9&cat=27&towns=1
But links that returned from results are without ?dep=9&cat=27&towns=1
How to force zend paginator to use passed $_GET params inside pagination link generation?
So that returned links were:
http://localhost/en/gallery/2?dep=9&cat=27&towns=1
http://localhost/en/gallery/3?dep=9&cat=27&towns=1
http://localhost/en/gallery/4?dep=9&cat=27&towns=1
etc...
or even
http://localhost/en/gallery/2/9/27/1
http://localhost/en/gallery/3/9/27/1
http://localhost/en/gallery/4/9/27/1
like they are defined inside route
etc...
Thanks

The view URL helper will always output params as part of the URL (separated by forward slashes) and doesn't, to my knowledge, support the GET parameter format.
I don't know what Routes_Categories class does, but working from the default ZF route classes try this:
$route = new Zend_Controller_Router_Route(
'/:lang/:category/:age/:dep/:cat/:towns/*',
array(
"dep" => 0,
"cat" => 0,
"towns" => 0
),
array(
"dep" => "[0-9]+",
"cat" => "[0-9]+"
)
);
$router->addRoute('ajax_gallery', $route);
The * supports any additional named params after your route. The above assumes lang, category and age are required, and dep, cat and towns are optional. Bear in mind if you want to set cat you have to set dep otherwise the route will get confused which variable is what.
In your controller access the page param via the following, which sets a default of 1.
$page = $this->_getParam('page', 1);
Access the URL via AJAX as: http://localhost/en/gallery/2/9/27/1
If you want the page param, use a named parameter: http://localhost/en/gallery/2/9/27/1/page/2
To get this route to work in your pagination you need to update your paginator view controls to use the right route. See: http://framework.zend.com/manual/en/zend.paginator.usage.html#zend.paginator.usage.rendering.example-controls
Look for the code where the URL is outputted and add the route name to the URL view helper. So replace code like this:
<?php echo $this->url(array('page' => $this->previous)); ?>
With:
<?php echo $this->url(array('page' => $this->previous), 'ajax_gallery'); ?>

Related

CakePHP RESTful API routing with custom querystring params

I'm using CakePHP 2.x for a RESTful API, I want to be able to handle requests in the following form
api/activity/17?page=1&limit=10
Typically CakePHP I think likes each param to be separated by the forward slash char and then each of these is mapped into the variables defined in the 2nd array argument of router::connect above. For exampple:
api/activity/17/1/10
In my case though this won't work so I am trying to pass a custom query string which I will then decode in my controller. My router connect is as follows:
So I am using router::connect as follow:
Router::connect('/api/activity/:queryString', [
'controller' => 'users',
'action' => 'activity',
'[method]' => 'GET',
'ext' => 'json',
],
[
'queryString' => '[0-9]+[\?]...[not complete]'
]);
I can't get the regular expression to accept the '?' which I am exscaping in the regex above. How can I achieve this or otherwise is there a better or easier way of sending the URL in the format I require.
You can get the URL parameters (among other methods) via $this->request->query;
So, in your example, add the following in method view() of app/Model/Activity.php:
<?php
// file app/Model/Activity.php
public function view($id)
{
// URL is /activity/17?page=1&limit=10
echo $this->request->query['page']; // echo's: 1
echo $this->request->query['limit']; // echo's: 10
}
See 'Accessing Querystring parameters' in the CakePHP book

Zend Custom Route if no match found

I have a ZF app with several modules as this: ( as usual )
root\
\application\
\default
\items
\me
\controllers
\views
The application uses the default routing like /module/controller/action;
What I want is this: if no match has been found for the default Zend Routing (no action / controller / module has been found ) then route to a desired path with the url endpoint spitted into parameters.
For example:
mydomain.lh/me -> will match the module me, controller index, action index ( as default )
mydomain.lh/my_category_name -> will match the module items, controller index, action index, params: category => my_category_name -> using the desired path route
no my_category_name module exists to match against
I have tried with this, into bootstrap.php:
public function _initRoutes ()
{
$router = $this->_front->getRouter(); // returns a rewrite router by default
$router->addRoute(
'cat-item',
new Zend_Controller_Router_Route('/:category',
array(
'module' => 'items',
'controller' => 'index',
'action' => 'index'))
);
}
Witch points to the correct location ( I know because I var_dump -ed the request url into the items/index/index action and the expected url and parameters were there, but if I do not do var_dump(something);exit; into the action, a blank page is served.
no output is made but also no error is generated, the request status is 200 - OK
Can anybody have a suggestion ?
Thank you!

Zend adding parameter to URL before generating view

The title might be misleading but I'm trying to do something very simple but cant figure it out.
Lets say I have a Question controller and show action and question id is the primary key with which I look up question details - so the URL looks like this
http://www.example.com/question/show/question_id/101
This works fine - So when the view is generated - the URL appears as shown above.
Now in the show action, what I want to do is, append the question title (which i get from database) to the URL - so when the view is generated - the URL shows up as
http://www.example.com/question/show/question_id/101/how-to-make-muffins
Its like on Stack overflow - if you take any question page - say
http://stackoverflow.com/questions/5451200/
and hit enter
The question title gets appended to the url as
http://stackoverflow.com/questions/5451200/make-seo-sensitive-url-avoid-id-zend-framework
Thanks a lot
You will have to add a custom route to your router, unless you can live with an url like:
www.example.com/question/show/question_id/101/{paramName}/how-to-make-muffins
You also, if you want to ensure that this parameter is always showing up, need to check if the parameter is set in the controller and issue a redirect if it is missing.
So, in your bootstrap file:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
public function _initRoutes ()
{
// Ensure that the FrontController has been bootstrapped:
$this->bootstrap('FrontController');
$fc = $this->getResource('FrontController');
/* #var $router Zend_Controller_Router_Rewrite */
$router = $fc->getRouter();
$router->addRoutes( array (
'question' => new Zend_Controller_Router_Route (
/* :controller and :action are special parameters, and corresponds to
* the controller and action that will be executed.
* We also say that we should have two additional parameters:
* :question_id and :title. Finally, we say that anything else in
* the url should be mapped by the standard {name}/{value}
*/
':controller/:action/:question_id/:title/*',
// This argument provides the default values for the route. We want
// to allow empty titles, so we set the default value to an empty
// string
array (
'controller' => 'question',
'action' => 'show',
'title' => ''
),
// This arguments contains the contraints for the route parameters.
// In this case, we say that question_id must consist of 1 or more
// digits and nothing else.
array (
'question_id' => '\d+'
)
)
));
}
}
Now that you have this route, you can use it in your views like so:
<?php echo $this->url(
array(
'question_id' => $this->question['id'],
'title' => $this->question['title']
),
'question'
);
// Will output something like: /question/show/123/my-question-title
?>
In your controller, you need to ensure that the title-parameter is set, or redirect to itself with the title set if not:
public function showAction ()
{
$question = $this->getQuestion($this->_getParam('question_id'));
if(!$this->_getParam('title', false)) {
$this->_helper->Redirector
->setCode(301) // Tell the client that this resource is permanently
// residing under the full URL
->gotoRouteAndExit(
array(
'question_id' => $question['id'],
'title' => $question['title']
)
);
}
[... Rest of your code ...]
}
This is done using a 301 redirect.
Fetch the question, filter out and/or replace URL-illegal characters, then construct the new URL. Pass it to the Redirector helper (in your controller: $this->_redirect($newURL);)

Render view from Zend_form

I try it via my Zend_form:
$output .= $this->_view->render('admin/form.phtml'
, array('id' => $this->getName()
, 'action' => $this->getAction()
, 'method' => $this->getMethod()
, 'enctype' => $this->getEnctype()
, 'data' => array('code' => $code
, 'name' => $name
, 'description' => $description)));
but when i <?php echo $this->enctype; ?> in admin/form.phtml i got nothing.
admin/form.phtml is rendered correctly
Choosing render just displays the output, Zend does not pass your data to the view. But Using view partials, you could achieve that.
From the documentation,
The Partial view helper is used to render a specified template within
its own variable scope. The primary use is for reusable template
fragments with which you do not need to worry about variable name
clashes. Additionally, they allow you to specify partial view scripts
from specific modules.

Zend_Navigation url generation issue

I use Navigation component for site menus. I also use let zend figure-out the selected menu item from request parameters - I guess this is done automatically. The only problem is, that for this to work, action and controller have to be specified in navigation configuration for every node. This also means that when zend generates links from route, action and controller information to appended to the generated link automatically.
Anyone had the same problem?
Zend manual section, explaining the Mvc navigation page features.
Example:
some route defined in bootstrap:
$router->addRoute('user_profile_tab', new Zend_Controller_Router_Route(
'profil/:user/:location/:tab/*',
array(
'action' => 'profile',
'controller' => 'user',
'user' => ($user ? $user->id : 0), //change later
'location' => 0 //inject appropriate value later
)
));
navigation container object:
$container = .....
......,
array(
'label' => tr('Privileges'),
'id' => 'user-profile-perms',
'type' => 'Zulu_Navigation_Page',
'controller' => 'user',
'action' => 'profile',
'route'=> 'user_profile_tab',
'params' => array('tab'=>Main_Lib_Common::NAVI_USER_TAB_PERMS)
)
);
the result when using
$page = $container->getById('user-profile-perms');
$page->href;
http://www.example.com/profil/1/0/3/controller/user/action/profile
WHY action and controler params in the navigation container object you ask. The $page->isActive() check needs this data to make a perfect match.
THE FIX:
extend mvc navigation page and provide an alternative getHref() method ... one that removes action, controller and module params when a route does not define them.
I have done this to fix this weird behaviour:
extend mvc navigation page
provide an alternative getHref() method
check for routes, not having action , controller and module parameters and remove them from params array before href generation.
This way the isActive matching will still work, as we didnt modify the route or navigation nodes in any way.