I am currently using Drupal 7 and I am writing a custom code such that users with a certain permission("use business dashboard") should see a menu item in their main menu. The problem is that only I(admin) can see this menu item. I have been able to create a custom permission on the permissions page and have set it to give access to "admin" and my user-specific role and have implemented the following code(nevermind the "xxxxxx" that is inplace of the module name, I would rather keep it anonymous for now, but just know that they are all in place of the machine-readable module name):
function xxxxxx_menu(){
$items = array();
$items['xxxxxxx'] = array(
'title' => 'Business Owner Dashboard',
'page callback' => '_xxxxxx_page',
'access arguments' => array('use business dashboard'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function xxxxxx_permission(){
return array(
'use business dashboard' => array(
'title' => t('Have access to business dashboard'),
'description' => t('Allow user to send out SMS messages via database query forms'),
),
);
}
When I log in as my test user which has the role-specific permission of "use business dashboard" I cannot see the menu item. I am sure this is incredibly simple, but I have been Googling and prodding at the code for hours. Any help would be greatly appreciated!
Can't figure this out either. Can you try to break down the access callback, if it didn't work, at least it'll give you a tip about what's going on.
Your code can go like this:
function xxxxxx_menu(){
$items = array();
$items['xxxxxxx'] = array(
'title' => 'Business Owner Dashboard',
'page callback' => '_xxxxxx_page',
'access callback' => 'my_custom_access_callback',
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function my_custom_access_callback()
{
if(user_access('use business dashboard'))
return TRUE;
return FALSE;
}
Till me if this works... Muhammad.
Related
I have two Drupal sites hosted on different servers. In the main they need to operate separately however site1 has one specific content type which I'd like to show in a list on site2.
I can't simply use feeds to import as the original has to remain and if edited, the changes be instantly reflected on both sites. Site2 has no requirement to edit the content - only show it.
The content is already being presented in a list on site1. The list was created using views.
My intention was to call the view on site2 using the following code in a custom module.
function site2_menu() {
$items = array();
$items['content-from-site1'] = array(
'title' => 'Content from Site1',
'page callback' => 'site_two_list',
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function site2_list() {
db_set_active('site1');
$content = views_embed_view('articles', 'default');
db_set_active('default');
return $content;
}
site1 DB is defined in the settings.php file.
However this isn't returning any data. Using the same approach on Site1 (without switching DBs) works fine.
Was I being over-optimistic in hoping this approach would work or am I missing something obvious?
If this isn't likely to work, what would the alternative be? I can do my own SQL query, but I'd prefer to use views for built in arguments, pagination, templates, etc.
Thanks.
I've not been able to use views_embed_view, however I have been able to use views_get_view to retrieve everything I need and iterate over the results myself. It's a very close second.
function site2_menu() {
$items = array();
$items['content-from-site1'] = array(
'title' => 'Content from Site1',
'page callback' => 'theme_site2_list',
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function site2_theme() {
return array (
'site2_list_page' => array(
'arguments' => array('content' => NULL),
'template' => 'templates/site2-list-page'
)
);
}
function theme_site2_list() {
db_set_active('site1');
$view = views_get_view('articles');
$view->base_database = "site1";
$view->init_display();
$view->pre_execute();
$view->execute();
db_set_active('default');
foreach ($view->result as $key => $data) {
$content[$key]['nid'] => $data->nid;
$content[$key]['title'] => $data->node_title;
$content[$key]['body'] => $data->field_body;
$content[$key]['image'] => $data->field_field_image;
}
return theme('site2_list_page', array('content' => $content));
}
Then in site2-list-page.tpl.php I can use the $content array to do what I need. It's not quite as clean as a simple views_embed_view, but it's a close second and allows the content from one site to be pulled to another fairly easily.
I am trying to write my first Drupal custom module (using drupal 6). I got the basic module working but I would like to add another page to the project. For example, right now my module's path looks like this: www.mysite.com/my_custom_module. I would like to add another page like this: www.mysite.com/my_custom_module/my_sub_page. I've tried adding a new .module and .info file but this does not work. I've also tried adding new items to the menu hook, like this:
my_custom_module.module:
function my_custom_module_menu(){
$items = array();
$items['my_custom_module'] = array(
'title' => "My Custom Module",
'page callback' => "my_custom_module_info",
'access callback' => true,
'type' => MENU_NORMAL_ITEM,
);
$items['my_custom_module/my_sub_page'] = array(
'title' => "My Sub Page",
'page callback' => "my_custom_module_sub_page_info",
'access callback' => true,
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function my_custom_module_info(){
$result = 'My Page URL was hit';
return $result;
}
function my_custom_module_sub_page_info(){
$result = 'My Sub Page URL was hit';
return $result;
}
In this example, if I go to .../my_custom_module it works fine. But, if I go to .../my_custom_module/my_sub_page, it still load, and displays my_custom_module. When I debug with a break point in each function, only my_custom_module_info is hit. Not the sub page. What am I doing wrong? I this even the correct way to create multi pages in a module? Just an FYI, each of these pages will have different audiences. The first page is to allow a user to submit some form data. The second is to allow an elevated user view the data.
Thanks
jason
I have this form which accepts user’s input. What I like to do is, base on that user input, I’d like to retrieve data and display it back to user.
So far, I have implemented hook_menu and registered respective url of the form, and implemented a submit function referred by “#submit” attribute of submit button. I’ve also implemented data retrieval code and works great.
Here’s my problem – I don’t know how to display retrieved data. I’ve tried several approaches in an attempt to find the solution.
First, with theme function, hoping that printing the return value of it would display the data. Second, setting “#action” element of form array with newly registered url, as I thought using the same url as form would only cause drupal to return that form instead and not my data. So, I creates a static variable and stores all the retrieved data in it;this is done inside submit function by the way. When I checked this variable inside menu callback, this variable is not set.
To summarize my problem, form has different access url than form submit, such as
Form url – http://....?q=mymodule/form
Submit url (value of ”#action”) – http://....?q=mymodule/execute
, and the data I’ve set inside submit function to static variable is not available in menu callback. How do I make the data available?
Here’s part of my code -
static $retrieved_data;
function mymodule_menu() {
$command = array();
$command['mymodule/form'] = array(
'title' => 'user input',
'page callback' => 'response',
'page arguments' => array('form'),
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
$command['mymodule/execute'] = array(
'title' => 'Search',
'page callback' => 'response',
'page arguments' => array('execute'),
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $command;
}
function _response($paRequest){
switch($paRequest){
case "form":
return drupal_get_form("_myform");
break;
case "execute":
return $retrieved_data;
break;
}
}
function _myform(&$form_state) {
$form['#action'] = url($base_path)."?mymodule/execute";
.....
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#submit' => array('_data_retrieve'),
);
return $form;
}
function _data_retrieve($form, &$form_state){
/*data retrieval code*/
........................
$retrieved_data = db_fetch_object($result);
}
Thanks a bunch
Your method seems a bit complicated there. When I make systems with a form, I tend to do it this way. In your MYMODULE_menu() I would change the 'page arguments' => array('form'), to 'page arguments' => array('NAME_OF_FORM_FUNCTION'), where NAME_OF_FORM_FUNCTION would be _myform in this case. I would rename it to MYMODULE_MYFORMNAME.
then create a function:
MYMODULE_MYFORMNAME_SUBMIT($form, &$state) {
// Enter code here to save the data from the form that is stored in $state
// to the database with an SQL query or a node_save($node) if you are
// creating a node.
}
After that you can retrieve the data from the database in your _data_retrieve function and call that on the page where you want to retrieve the data.
I want to add some tabs in the "node/%/edit" page from my module called "cssswitch".
When I click "Rebuild Menus", the two new tabs are displayed, but they are displayed for ALL nodes when editing them, not just for the node "cssswitch". I want these new tabs to be displayed only when editing node of type "cssswitch".
The other problem is when I clear all cache, the tabs completely dissapear from all edit pages. Below is the code I wrote.
function cssswitch_menu_alter(&$items) {
$node = menu_get_object();
//print_r($node);
//echo $node->type; //exit();
if ($node->type == 'cssswitch') {
$items['node/%/edit/schedulenew'] = array(
'title' => 'Schedule1',
'access callback'=>'user_access',
'access arguments'=>array('view cssswitch'),
'page callback' => 'cssswitch_schedule',
'page arguments' => array(1),
'type' => MENU_LOCAL_TASK,
'weight'=>4,
);
$items['node/%/edit/schedulenew2'] = array(
'title' => 'Schedule2',
'access callback'=>'user_access',
'access arguments'=>array('view cssswitch'),
'page callback' => 'cssswitch_test2',
'page arguments' => array(1),
'type' => MENU_LOCAL_TASK,
'weight'=>3,
);
}
}
function cssswitch_test(){
return 'test';
}
function cssswitch_test2(){
return 'test2';
}
Thanks for any help.
hook_menu_alter() is only called during the menu building process, so you can't do dynamic node type checks within that function.
However, to achieve what you want, you can do this with a custom access callback as follows:
// Note, I replaced the '%' in your original code with '%node'. See hook_menu() for details on this.
$items['node/%node/edit/schedulenew2'] = array(
...
'access callback'=>'cssswitch_schedulenew_access',
// This passes in the $node object as the argument.
'access arguments'=>array(1),
...
);
Then, in your new custom access callback:
function cssswitch_schedulenew_access($node) {
// Check that node is the proper type, and that the user has the proper permission.
return $node->type == 'cssswitch' && user_access('view cssswitch');
}
For other node types, this function will return false, thus denying access, and thus removing the tab.
Hi I need to create a module in drupal to display some data, not being a drupal developer and after reading a couple of tutorials, i cant seem to display anything.
I have the next code:
<?php
function helloworld_perm() {
return array('access helloworld content');
}
function helloworld_listado(){
return "yea";
}
function helloworld_menu(){
$items = array();
$items["listado"] = array(
'title' => t('Listado de empresas'),
'callback' => 'helloworld_listado',
'access' => array('access helloworld content'),
'type' => MENU_NORMAL_ITEM
);
return $items;
}
When i enter /listado i get a Access denied
You are not authorized to access this page.
Any idea what im doing wrong?
If i go to the admin->module->permissions, i have checked the permision for all roles to access hellowold content.
Ty!
From the way that your menu array is structured in helloworld_menu(), I'm assuming that this is Drupal 6. If so, you need to rename 'access' to 'access arguments'. See http://api.drupal.org/api/function/hook_menu/6.
The Drupal API documentation also includes a heavily-commented page_example.module that's doing basically what you're doing here, which you might want to check out: http://api.drupal.org/api/file/developer/examples/page_example.module/6/source
Hope that helps!
Oh. And don't forget to clear your cache afterwards from the "Clear cache" button on Administer >> Site configuration >> Performance.
=> t('Listado de empresas'),
'page callback' => 'helloworld_listado',
'access arguments' => array('access helloworld content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
Note that , MENU_NORMAL_ITEM being the default value for type, you do not need to specify it.
Also, as our esteemed webchick just said
It seems you are using a mix of Drupal 5 (array contents) and Drupal 6 (no $may_cache, $items indexed by path) syntaxes for hook_menu.
If you are using Drupal 6, this should look like:
<?php
function helloworld_perm() {
return array('access helloworld content');
}
function helloworld_listado(){
return "yea";
}
function helloworld_menu(){
$items = array();
$items["listado"] = array(
'title' => t('Listado de empresas'),
'page callback' => 'helloworld_listado',
'access arguments' => array('access helloworld content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
?>
Note that, MENU_NORMAL_ITEM being the default value for 'type', you do not need to specify it.
Also, as our esteemed webchick just said, you can find a detailed explanation on the page she points to.
just FYI , above link moved to
http://api.drupal.org/api/examples/page_example--page_example.module/6