I've got a Drupal site which uses a custom field for a certain type of node (person_id) which corresponds to a particular user. I want to create a view so that when logged in, a user can see a list of nodes 'tagged' with their person_id. I've got the view working fine, with a url of my-library/username but replacing username with a different username shows a list of all nodes tagged with that user. What I want to do is stop users changing the URL and seeing other users' tagged nodes. How can I do this? Is there somewhere where I can dictate that the only valid argument for this page is the one that corresponds with the current logged in user's username?
person_id = uid?
In this case, add argument with user:uid, then in Validation options select PHP Code, read comment of this field carefully:
Enter PHP code that returns TRUE or
FALSE. No return is the same as FALSE,
so be SURE to return something if you
do not want to declare the argument
invalid. Do not use . The
argument to validate will be
"$argument" and the view will be
"$view". You may change the argument
by setting "$handler->argument".
Add this code:
global $user;
$account = user_load('name'=>arg(1));
$handler->argument = $user->uid;
return $account->uid == $user->uid;
I'm not sure how you have setup your view, which gives some different options to solve this. A way that should work would be to set the default argument be the logged users id/username and remove the argument from the url.
Alternatively you could create your own filter which requires some work with the views API, but gives more control.
Related
I have a permissions problem in Drupal. I want users to be able to create a certain node type, but there are two different paths I need to give them permissions for to let them do this. The type is content created by a module called isbn2node, and there are two ways to make content through it, each with different paths:
?=node/add/isbn2node-book
?=node/add/isbn2node_book/isbn2node
One has an underscore and the other one has a hyphen. The first path leads to a form that lets users enter information on a book manually; the second path lets them enter an ISBN, searches for it, and populates the form for them based on the results.
I've changed permissions in the People menu so they can add isbn2node-book content manually using the first path, but there isn't an option to let them use the second method. Aliasing the url so it didn't have node/add in the path didn't work either.
Creating a duplicate content type seems like an ugly solution to this; is there a more elegant way to let users access that second path?
A little code in a custom module using hook_node_access should do it.
$node is either a node object or the machine name of the content type on which to perform the access check (if the node is being created then the $node object is not available so it will be a string instead).
So this should do it:
function MY_MODULE_node_access($node, $op, $account) {
if ($op == 'create') {
$type = $node;
if($type == 'book' && $account->uid) return NODE_ACCESS_ALLOW;
}
}
I figured this out, and the issues I was having were specific to this content type. The ISBN2Node module requires users to have the Administer Nodes permission to use its lookup and bulk import features.
There is some extra code for the module's hook_permission and hook_menu sections submitted as a fix in the module's issues thread.
How can I change the title given to the /user/[uid] page from Your account to Welcome [user name] for logged-in user, where [user name] is the username for the currently logged-in user?
Use hook_menu_alter.
Alter the data being saved to the {menu_router} table after hook_menu is invoked.
Code sample:
function MYMODULE_menu_alter()
{
global $user;
if($user->uid != 0)
$items['user']['title'] = 'Welcome ' . $user->name;
}
You should be able to accomplish this with the Menu token module:
Menu Token module provides tokens, that could be used in title or in path of menu items (links).
(It requires the popular Token module.)
Note that with Drupal 7.23, the user.module includes a 'title callback' to determine if the user is logged in or not, and respond with a corresponding title.
Code that worked for me (through theme template, instead of a custom module):
function YOURTHEME_menu_alter(&$items) {
$items['user']['title callback'] = 'YOURTHEME_user_menu_title';
}
function YOURTHEME_user_menu_title() {
global $user;
return user_is_logged_in() ? t($user->name) : t('User account');
}
The String Overrides module should make this easy.
In Drupal 7, hook_menu() and hook_menu_alter() are just invoked when the data about routes implemented from modules needs to be refreshed, for example when a module is enabled, disabled, installed, or uninstalled. An implementation of hook_menu_alter() that uses the name of the currently logged-in user in the title would show the same username for different users.
Differently, the title callback associated with a route is called every time the page associated with that route is rendered.
The correct code would be similar to the following one.
function mymodule_menu_alter(&$items) {
$items['user']['title callback'] = 'mymodule_user_profile_title';
}
function mymodule_user_profile_title() {
global $user;
return user_is_logged_in() ? t('Welcome, #name', array('#name' => format_username($user))) : t('User account');
}
Notice that the first argument of t() needs to be a literal string, not a dynamic value as in t($user->name) because the database table containing the string translations would not contain the translation for every username used in a site.
It is also wrong because the shown username is invariant respect the language used on a site: For example, in an Italian site, a username like Albert isn't translated to Alberto, nor Vincent is translated to Vincenzo.
When showing a username in the UI, it is always preferable to use format_username(), which allows to third-party module to change what shown as username. (For example, a module could show the content of a user field, instead of showing the login username.)
If you aren't willing to write custom code, you could use the String Overrides module. If you don't want to use any module just for changing the title of the user profile page, you could add the following code in the settings.php file used for the site.
$conf['locale_custom_strings_en'][''] = array(
'My account' => 'Welcome to my site'
);
Notice that, either using the String Overrides module or adding the $conf['locale_custom_strings_en'][''] array in the settings.php file, you cannot:
Provide a string that changes basing on the logged-in user (which is what the question is asking for)
Provide a string that is used only on specific pages
The latter case could be a pro or a con. If the string that needs to be changed is generic enough, it would be replaced even when it should not.
i need to display the contents added by that user...
i have designed a view to display the result.. but it displays the results of all users.....
i need to display the contents added by that user...
when i pass the argument of userid it works, but is there any dynamic way to do that....
If all you need is a list of nodes by the current user, the easiest way is to use the User:Current filter. Just click the [+] next to 'Filters', choose 'User:Current' from the list, click the 'Add' button and set the filter to 'Yes'.
The argument-method as described by streetparade (using the 'User: Uid' argument) is useful if you want users to see the list of other users as well. Suppose that your view's url is www.example.com/my-content. If you add a user argument, user #3 could see what user #7 has posted on www.example.com/my-content/7. If you want that, use the argument. If you do not want that, use the filter.
Use This
<?php
global $user;
$userId = $user->uid;
?>
You can access all this way
(source: chromaticsites.com)
I'm currently wrestling with a views relationship-argument puzzle.
I have a Flag setup called Favorites, so that users can favorite site content. I also am using Content Profiles and Pathauto. Now I'm adding a views content attachment to the user content profile to display the user's chosen favorites.
Pathauto's default content profile path is: member/[title-raw] - so that a typical alias for a user's profile page is: member/john-smith (please bear in mind that the profile node id isn't the same as the user id)
And here's my views setup:
Relationship: flags:favorites - BY: Any user
Argument: This is where my understanding breaks down. I need to somehow get the username or uid out of the URL of the current profile.
Any ideas of the correct argument to get this thing to work? I've been trying out all the possibilities that occur to me, and so far no luck.
Thanks
In your View setup, click on + in Arguments to add an argument.
In your argument setup, select "User" from the "Groups" drop down.
Check "User: Name"
Click "Add" button
Save your view
As long as this is your only argument, you just have to pass in user name in the URL. In your example, so see the view for john-smith, you would navigate to http://example.com/viewname/john-smith.
That would be for page type view.
If you are creating a block view type, you cannot pass arguments in the URL. For a block type view, follow these steps:
In your View setup, click on + in Arguments to add an argument.
Select "PHP Code" for "Default argument type"
Enter the following for the PHP code,
if (arg(0) == 'viewname' && arg(1) != '') {
return arg(1);
}
Now that block will get arguments from the URL, similar to what occurs for a page view.
if you're willing to use custom php code in order to fetch the argument, http://api.drupal.org/api/function/drupal_get_normal_path/6 is your friend. you can pass it the alias you're visitting with arg(0).'/'.arg(1)
When a user login , the user will be redirect to a user profile page, which has a My account field set.
the field set has 2 fields, "Username: ", "Email address:". those 2 fields are generated by drupal.
those 2 field contained in a form which has a id ("user_profile_form") . I want to change the order of those 2 fields.
I have tried to intercept 'user_profile_form' , inside hook_form_alter.
code as follow:
$form['account']['name']['#weight'] = 1;
but that did not success, drupal did not even rendering the 'name' field, so no username: showed on browser.
What you did is absolutely correct, and probably did work. You can change the weight of the fields with the method described above.
The username field is not always rendered. The reason is that a persmission is required: change own username. If that perm is not set, you wont be allowed to alter you username and the field wont be shown.
Info on debugging.
Your info alone is not quite enough to debug. From what you describe, you are doing the right thing, but other modules could be making things a bit tricky for you. The devel module is quite good when it comes to debugging, ti defines two functions I use a lot when debugging:
dpm() pretty prints the variable to the message area using krumo.
dd() Prints / saves a variable to a log file. Useful when you can't view messages on the screen.
I would suggest that you look at the $form variable before and after you alter it.
Things that could make it go wrong:
Did you remember to pass the $form variable by reference using the & notation?
Is another module altering your form after you?
Are you checking for the correct form id, so you alter the correct form?
These are some pointers, before you bring more info, all I can do is guess to what your problem exactly can be. I did something like this a few days ago so I know what you describe shouldn't be a problem.