how to remove action name from URL in cakephp2 - .htaccess

may be duplicate but I don't get any proper answer or help
actually I want to do like:
my current URL is : http://mysite.com/MyController/view/page1
but I want something like :http://mysite.com/MyController/page1
means I want to hide action name from URL.
I have used
Router::connect('/:controller/:id',array('action' => 'view'),array('id' => '[0-9]+'));
but its not working for me
below one working fine but
Router::connect('/:controller/*', array('action' => 'view'),array('id' => '[0-9]+'));
it applies for all controller but I wanted to apply for specific controller

use
Router::connect('/MyController/:id', array('controller' => 'MyController','action' => 'view'),array('id' => '[0-9]+'));

You can use Cake's routing to get this to work.
Add the following to your app/Config/routes.php
Router::connect('/Controller/page1', '/Controller/view/page1');
But you will have to add a route for every 'page'.
You can use a wildcard route to match everything starting with /Controller/:
Router::connect('/Controller/*', '/Controller/view/');
Or, without touching routes:
class FooController extends AppController
public function index($stub) {
$data = $this->findByStub($stub);
if (!$data) {
die('page not found');
}
$this->set('data', $data);
}
}
}
Which allows you to have urls such as /foo/page1
(The routine looks for a Foo with a stub field matching 'page1')
This works, but you will loose the benefit of reverse routing which means you can make links like this: $this->Html->link(array('controller'=>'foo', 'action'=>'view', 'page1'); which cake will automagically rewrite to produce: /foo/page1

use this code
Router::connect('/:controller/*', array('action' => 'view'),array('id' => '[0-9]+'));

Try the following code for your controller, Here am using GroupsController as an example
You add this in your app\Config\routes.php
Router::connect('/groups/:slugParam', array('controller' => 'groups', 'action' => 'index'), array('slugParam' => '[a-zA-Z0-9]+'));
This should redirect all requests of the form
http://www.site.com/groups/* to http://www.site.com/groups/index
( * => whatever comes after the controller name )
So now i have to alter my default index function in GroupsController to reflect this change
<?php
App::uses('AppController', 'Controller');
class GroupsController extends AppController {
public function index($id = null) {
//pr($this->request->params); this where all data is intercepted...
if(isset($this->request->params['slugParam']) && !empty($this->request->params['slugParam'])) {
// i have a slug field in groups databsae and hence instead of id am using slug field to identify the post.
$data = $this->Group->findBySlug($this->request->params['slugParam']);
$this->set('group', $data);
$this->render('/groups/view');
}
}
}
?>

use this code
Router::connect('/MyController/:id', array('controller' => 'MyController','action' => 'view'),array('id' => '[0-9]+'));

Related

How to perform a redirect in Enlight_Event_EventArgs object subscriber in Shopware 5?

I have a subscriber to the event
'Shopware_Modules_Admin_SaveRegister_Successful'
and after certain actions, I want to perform a redirect in the end, but the $args object does not have a subject which means that I cannot call the $controller = $args->getSubject(); on it and perform a redirect.
Is there another way to perform a redirect inside of the callback function of this event? 'Shopware_Modules_Admin_SaveRegister_Successful' => 'onRegisterSuccessful'
public function onRegisterSuccessful($args){
$controller = $args->getSubject();
$controller->redirect(
array(
'controller' => 'profile',
'action' => 'verify',
'name' => $name
)
);
}
Try like this. Note that you need to exit() after the redirect, because after the event is fired, Shopware makes its own redirect to the customer dashboard.
public static function getSubscribedEvents()
{
return [
'Shopware_Modules_Admin_SaveRegister_Successful' => 'onregister'
];
}
public function onRegister(\Enlight_Event_EventArgs $args)
{
$url = Shopware()->Front()->Router()->assemble([
'controller' => 'profile',
'action' => 'verify'
]);
header('Location: ' . $url, true);
exit();
}
Your option would be to go a bit higher and register an controller's postDispatch event. There you can redirect.

How to implement a pagination for a search module in Zend Framework 2?

I have a module Search in my ZF2 application. The user fills in a search form out and gets a list of courses.
Now I'm adding the pagination to the module. The paginator is basically working: I can retrieve data over it and the pagination is displayed correctly (pagelinks 1-7 for 70 found courses with the dafault setting 10 items per page).
But it's still not usable. When I click on a pagelink, the form POST data is lost. I know -- it cannot work the way, how I implemented it (see the code below). But I have no idea, how to do it correctly, in order to eep checking the form data and nonetheless be able to use pagination.
That is my code:
Table class Search\Model\CourseTable
class CourseTable {
...
// without pagination
// public function findAllByCriteria(CourseSearchInput $input) {
// with pagination
public function findAllByCriteria(CourseSearchInput $input, $pageNumber) {
...
$select = new Select();
$where = new Where();
$having = new Having();
...
// without pagination
// $resultSet = $this->tableGateway->selectWith($select);
// return $resultSet;
// with pagination
$adapter = new \MyNamespqce\Paginator\Adapter\DbSelect($select, $this->tableGateway->getAdapter());
$paginator = new \Zend\Paginator\Paginator($adapter);
$paginator->setCurrentPageNumber($pageNumber);
return $paginator;
}
...
}
Search\Controller\SearchController
class SearchController extends AbstractActionController {
public function searchCoursesAction() {
$form = $this->getServiceLocator()->get('Search\Form\CourseSearchForm');
$request = $this->getRequest();
if ($request->isPost()) {
$courseSearchInput = new CourseSearchInput();
$form->setInputFilter($courseSearchInput->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$courseSearchInput->exchangeArray($form->getData());
// without pagination
// $courses = $this->getCourseTable()->findAllByCriteria($courseSearchInput);
// with pagination
$page = $this->params()->fromRoute('page');
$paginator = $this->getCourseTable()->findAllByCriteria($courseSearchInput, $page);
} else {
$paginator = null;
}
} else {
$paginator = null;
}
return new ViewModel(array(
'form' => $form,
// without pagination
// 'courses' => $courses,
// with pagination
'paginator' => $paginator,
'cities' => ...
));
}
...
}
How to get it working?
I also have the same problem, and I have solved it. But this is not good way. May be the idea will help you.
I solved it as follow: (Search pagination for Zend tutorial album module)
I build two action in controller named "search" and "index".
Whenever the search form submitted, it always post the value to search action. Search action build the url with search parameters, and redirect to index to disply search result.
And when the pagination links clicked, then posted values are passed through url. So whenever index action ask for search parameters, it always get the values in same format.
I defined route as follows:
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/:action][/:id][/page/:page][/order_by/:order_by][/:order][/search_by/:search_by]',
'constraints' => array(
'action' => '(?!\bpage\b)(?!\border_by\b)(?!\bsearch_by\b)[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
'page' => '[0-9]+',
'order_by' => '[a-zA-Z][a-zA-Z0-9_-]*',
'order' => 'ASC|DESC',
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
There is a parameter named "search_by", which will keep all search parameters as a json string. This is the point, which is not good I know, but have not find any other way yet.
"Search" action build this string as -
public function searchAction()
{
$request = $this->getRequest();
$url = 'index';
if ($request->isPost()) {
$formdata = (array) $request->getPost();
$search_data = array();
foreach ($formdata as $key => $value) {
if ($key != 'submit') {
if (!empty($value)) {
$search_data[$key] = $value;
}
}
}
if (!empty($search_data)) {
$search_by = json_encode($search_data);
$url .= '/search_by/' . $search_by;
}
}
$this->redirect()->toUrl($url);
}
And next index action decode the string, do necessary action, and also send the json string to view.
public function indexAction() {
$searchform = new AlbumSearchForm();
$searchform->get('submit')->setValue('Search');
$select = new Select();
$order_by = $this->params()->fromRoute('order_by') ?
$this->params()->fromRoute('order_by') : 'id';
$order = $this->params()->fromRoute('order') ?
$this->params()->fromRoute('order') : Select::ORDER_ASCENDING;
$page = $this->params()->fromRoute('page') ? (int) $this->params()->fromRoute('page') : 1;
$select->order($order_by . ' ' . $order);
$search_by = $this->params()->fromRoute('search_by') ?
$this->params()->fromRoute('search_by') : '';
$where = new \Zend\Db\Sql\Where();
$formdata = array();
if (!empty($search_by)) {
$formdata = (array) json_decode($search_by);
if (!empty($formdata['artist'])) {
$where->addPredicate(
new \Zend\Db\Sql\Predicate\Like('artist', '%' . $formdata['artist'] . '%')
);
}
if (!empty($formdata['title'])) {
$where->addPredicate(
new \Zend\Db\Sql\Predicate\Like('title', '%' . $formdata['title'] . '%')
);
}
}
if (!empty($where)) {
$select->where($where);
}
$album = $this->getAlbumTable()->fetchAll($select);
$totalRecord = $album->count();
$itemsPerPage = 2;
$album->current();
$paginator = new Paginator(new paginatorIterator($album));
$paginator->setCurrentPageNumber($page)
->setItemCountPerPage($itemsPerPage)
->setPageRange(7);
$searchform->setData($formdata);
return new ViewModel(array(
'search_by' => $search_by,
'order_by' => $order_by,
'order' => $order,
'page' => $page,
'paginator' => $paginator,
'pageAction' => 'album',
'form' => $searchform,
'totalRecord' => $totalRecord
));
}
All the sorting and paging url contain that string.
If you know all the searching paarameters before, then you can define that at route, and pass like the same way without json string. As I have to build a common search, I have build a single string.
Source code for "Album search" is available in git hub at https://github.com/tahmina8765/zf2_search_with_pagination_example.
Live Demo: http://zf2pagination.lifencolor.com/public/album
#Sam & #automatix in the question comments are both right. My suggestion (though I'm looking for a simpler alternative) is to construct a segment route, which covers all of the options that you're likely to need and start with a standard form POST request.
Then, after the request is validated, pass the form data to the paginationControl helper as follows:
$resultsView = new ViewModel(array(
'paginator' => $paginator,
'routeParams' => array_filter($form->getData())
));
Then, in your view template, set the route parameters in the paginationControl view helper:
<?php echo $this->paginationControl($paginator, 'Sliding', 'paginator/default',
array('routeParams' => $routeParams)
) ?>
I've used array_filter here because it's a really simple way of removing any element from the form data that's null, empty or so on. That way you don't pass in extra data that you don't need.

drupal 6: how to modify the display of the comment module

Before posting comments a message is shown:
Login or register to post comments
I want to modify the output of the 2 links "login" and "register", mainly I want to add some classes to the links to format it nicely with some img. buttons of different colors
I really need to "tell" the output to put and , and by default doesn't have no class....
I know it can be done with some hook or something but I can't find no info about that ...
The piece responsible for that line is locate in theme_comment_post_forbidden in drupal_root/modules/comment/comment.module
it looks like this
function theme_comment_post_forbidden($node) {
global $user;
static $authenticated_post_comments;
if (!$user->uid) {
if (!isset($authenticated_post_comments)) {
// We only output any link if we are certain, that users get permission
// to post comments by logging in. We also locally cache this information.
$authenticated_post_comments = array_key_exists(DRUPAL_AUTHENTICATED_RID, user_roles(TRUE, 'post comments') + user_roles(TRUE, 'post comments without approval'));
}
if ($authenticated_post_comments) {
// We cannot use drupal_get_destination() because these links
// sometimes appear on /node and taxonomy listing pages.
if (variable_get('comment_form_location_'. $node->type, COMMENT_FORM_SEPARATE_PAGE) == COMMENT_FORM_SEPARATE_PAGE) {
$destination = 'destination='. rawurlencode("comment/reply/$node->nid#comment-form");
}
else {
$destination = 'destination='. rawurlencode("node/$node->nid#comment-form");
}
if (variable_get('user_register', 1)) {
// Users can register themselves.
return t('Login or register to post comments', array('#login' => url('user/login', array('query' => $destination)), '#register' => url('user/register', array('query' => $destination))));
}
else {
// Only admins can add new users, no public registration.
return t('Login to post comments', array('#login' => url('user/login', array('query' => $destination))));
}
}
}
}
I suggest modifying your theme's template.php and adding a new function phptemplate_comment_post_forbidden($node) where you'll copy the contents of theme_comment_post_comments and do the necessary modifications.

drupal 6 : node.tpl.php $links variable, where to configure the content?

I need to define the order of the $links output
now I have 2 modules displaying its contents on that:
comments and addthis
where can I define the order of the and modify it's settings for nodes...
even customize a little bit the display?
Edit: links weights can be changed using http://drupal.org/project/linkweights
I am not sure there is any kind of UI for reordering/customizing the node links.
However you can accomplish this in a couple of ways:
Create a custom module that implements hook_link_alter() and perform the customizations.
/**
* hook_link_alter() implementation
* for more details see
* http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hook_link/6
* http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hook_link_alter/6
*/
function mymodule_link_alter(&$links, $node) {
foreach ($links as $link => $values) {
// do something with $link
}
return $links;
}
You can go even further and create an administration page that will get all the links, output them in a sortable table (a la /admin/build/block) and save the order in a variable. Ah, your module needs to have the highest weight in order to catch all the other links.
--OR--
Modify your theme's template.php and add the mytheme_preprocess_node() function or edit it or phptemplate_preprocess_node() if it exists
function phptemplate_preprocess_node(&$vars) {
$links= $vars['node']->links;
// uncomment the next line to see the current links
//var_dump($links);
// add a new link
$link_all = array(
'title' => 'See all nodes',
'href' => PATH,
//'attributes' => array('class' => 'link_class', 'id' => 'link_id', 'title' => 'link title'),
);
$links['link_all'] = $link_all;
//Modify an existing link. in this case the above added one
$links['link_all']['title'] = t('This is my custom text');
$vars['links'] = theme_links($links);
}
To reorder see http://drupal.org/node/44435#comment-861385

Drupal 6: Working with Hidden Fields

I am working on an issue i'm having with hooking a field, setting the default value, and making it hidden. The problem is that it is taking the default value, but only submitting the first character of the value to the database.
//Here is how I'm doing it
$form['field_sr_account'] = array( '#type' => 'hidden', '#value' => '45');
I suppose there is something wrong with the way that I have structured my array, but I can't seem to get it. I found a post, http://drupal.org/node/59660 , where someone found a solution to only the first character being submitted
//Here is the format of the solution to the post - but it's not hidden
$form['field_sr_account'][0]['#default_value']['value'] = '45';
How can I add the hidden attribute to this?
Have you tried using #default_value insted of #value?
Also if you're trying to pass some data to the submit that will not be changed in the form you should use http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html#value .
The answer was actually to set the value and the hidden attribute separately, then set the value again in the submit handler using the following format.
I'm not sure if it's all necessary, I suppose I probably don't need to assign it in the form alter, but it works, so I'm going to leave it alone...
$form['#field_sr_account'] = $club;
$form['field_sr_account'] = array( '#type' => 'hidden','#value' => $club);
}
}
/*in submit handler, restore the value in the proper format*/
$form_state['values']['field_sr_account'] = array('0' => array('value' => $form['#field_sr_account']));
An interesting solution from http://drupal.org/node/257431#comment-2057358
CCK Hidden Fields
/**
* Implementation of hook_form_alter().
*/
function YourModuleName_form_alter(&$form, $form_state, $form_id) {
if (isset($form['type']) && isset($form['#node'])) {
### Make a CCK field becoming a hidden type field.
// ### Use this check to match node edit form for a particular content type.
if ($form_id === 'YourContentTypeName_node_form') {
$form['#after_build'] = array('_test_set_cck_field_to_hidden');
}
}
}
function _test_set_cck_field_to_hidden($form, &$form_state) {
$form['field_NameToBeHidden'][0]['value']['#type'] = 'hidden';
$form['field_NameToBeHidden'][0]['#value']['value'] = 'testValue';
return $form;
}

Resources