Drupal user_hook in custom module - drupal

Modifying download_count module to include information about users who downloaded files. Want to show this info on users' profile pages.
Here's the code:
function download_count_user($op, &$edit, &$account, $caterory = NULL) {
if ($op == 'view')
{
$result = db_query("SELECT filename FROM file_downloads_users WHERE user_id = %d", $account->uid);
while ($file_array = db_fetch_object($result)) {
$file_str .= $file->filename . '<br/>';
}
$items['downloads'] = array(
'title' => t('Files'),
'value' => $file_str,
'class' => 'member'
);
return array(t('Downloads')=>$items);
}
}
Doesn't give me any errors but doesn't show anything on My Account page either.

You don't want to modify a module. Drupal is built very very carefully to avoid having to hack core or contrib. Unless of course you are contributing a patch back.
The right way is to build your own custom module to do this (that would require the user downloads module) and implement the hook almost exactly what you're doing here.
The function is getting run (module enabled, var_dump ing or krumo'ing causes output?, cache cleared)
The way you are keying your variables is for Drupal 5.x and below. In D6, you add to $account->content. Which version of drupal are you using?
Check out user_user() (in user.module):
$account->content['user_picture'] = array(
'#value' => theme('user_picture', $account),
'#weight' => -10,
);

$account->content['summary']['file_downloads'] = array(
'#type' => 'user_profile_item',
'#title' => t('File Downloads'),
'#value' => $file_str,
'#weight' => 1
);

Related

Only partial theming of custom form

I've constructed a custom module to create a form. Now I'm stuck on the theming. I already have a CSS stylesheet for the form, since my company is part of the government and they have a preset branding. So I wanted to change the HTML used by the default form theme functions of Drupal thus implementing the correct style.
But only the form-tag of the form gets rendered. The fieldset and elements are not rendered. When the theme functions are removed the default theming kicks in and the form renders normally (but of course without the requested theming).
What I have tried so far:
Added a hook_theme function to add theme functions
function publicatieaanvraagformulier_theme() {
return array(
'publicatieaanvraagformulier_form' => array(
'arguments' => array("element" => NULL)
),
'publicatieaanvraagformulier_fieldset' => array(
'arguments' => array("element" => NULL)
),
'publicatieaanvraagformulier_form_element' => array(
'arguments' => array(
"element" => NULL,
"value" => NULL
)
)
);
}
Added ['#theme'] to the form-element, fieldset-element and the form-elements
$form['#theme'] = "publicatieaanvraagformulier_form";
$form['groep'] = array(
'#title' => t("Please fill in your details"),
'#type' => "fieldset",
'#theme' => "publicatieaanvraagformulier_fieldset"
);
$form['groep']['organisatie'] = array(
'#title' => t("Organization"),
'#type' => "textfield",
'#attributes' => array("class" => "text"),
'#theme' => "publicatieaanvraagformulier_form_element"
);
Added the actual theme function based on the default ones in form.inc
function theme_publicatieaanvraagformulier_form($element) {
function theme_publicatieaanvraagformulier_fieldset($element)
function theme_publicatieaanvraagformulier_form_element($element, $value)
I haven't included the code of these functions because even with the default themefunctions code, they don't work. Therefor I assume they are not the source of the problem.
The form is called
//Get the form
$form = drupal_get_form('publicatieaanvraagformulier');
//Add messages
$errors = form_get_errors();
if (!empty($errors)) {
$output .= theme("status_messages","error");
}
//Show form
$output .= $form;
return $output;
I haven't found similar 'complicated' examples of theming a form, but have pieced together the former from books and online searches.
Hopefully someone has an answer to this problem (point out the mistake I made).
Greetings
Jeroen

Create content in Drupal based on options in a drop down

I am working on a Drupal site that needs to have a 'careers' page. I have a list of twenty or so jobs, and 30 or so locations where these jobs may be available.
What I am looking to do is make it so, when a job becomes available, all that needs to be done is the user selects the job title and the location where it is available and it will create the posting with the job description and other info I have along with the info for that location.
Another hurtle I am running into is making it so I can have multiple instances... ex. If the same job is available at two or more locations.
I have been trying to wrap my mind around how I am going to make this work and am coming up blank. If anyone has an idea to point me in the right direction, it would be appreciated.
Sounds like a pretty common use case; if it was me I'd approach it like this:
Create a 'Job' content type
Add a new 'Location' Vocabulary
Add a term reference field on the 'Job' content type to the 'Location' vocabulary, with unlimited values (or the maximum no. of locations you want to allow per job).
Create a custom form for your admins, something like:
function MYMODULE_add_job_form($form, &$form_state) {
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#maxlength' => 255,
'#required' => TRUE
);
// Load the vocabulary (the machine name might be different).
$vocabulary = taxonomy_vocabulary_machine_name_load('location');
// Get the terms
$terms = taxonomy_get_tree($vocabulary->vid);
// Extract the top level terms for the select options
$options = array();
foreach ($terms as $term) {
$options[$term->tid] = $term->name;
}
$form['locations'] = array(
'#type' => 'select',
'#title' => t('Locations'),
'#options' => $options,
'#multiple' => TRUE,
'#required' => TRUE
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Add job')
);
return $form;
}
Create a custom submit handler for the form to add the new node programatically:
function MYMODULE_add_job_form_submit($form, &$form_state) {
$location_tids = array_filter($form_state['values']['locations']);
$node = new stdClass;
$node->type = 'job';
$node->language = LANGUAGE_NONE;
node_object_prepare($node);
$node->title = $form_state['values']['title'];
$node->field_location_term_ref[LANGUAGE_NONE] = array();
foreach ($location_tids as $tid) {
$node->field_location_term_ref[LANGUAGE_NONE][] = array(
'tid' => $tid
);
}
node_save($node);
$form_state['redirect'] = "node/$node->nid";
}
You'll need to add a page callback for that form obviously, and there'll likely be some small changes you'll need to make (names of fields etc), but it should give you a good starting point. You'll also need to load the location taxonomy terms at some point to extract the description info you mentioned...you can use taxonomy_term_load() to do that.

Drupal 7 .10 hook_menu implementation error

I am trying to figure out why hook_menu implementation is not working anymore after upgrade from 7.4 to 7.10 for a custom module Menu links were working properly until update to latest version. after update all custom module links are deleted from table menu_links and menu_router.
After many attempts, I also installed a fresh version for D7.10 and created a simple custom module with one item link only (see code below) for testing purpose only. The link is not implemented once the module is enabled. Tables menu_links and menu_routers are not updated.
I have been looking around many possible errors and solution without success.
Really stacked now. What makes me doubt is that I do not see anybody else having the same issue... Any suggestion? Thank you
function misite_menu() {
$items = array();
$items['a/main'] = array(
'title' => 'main',
'page callback' => 'main',
'description' => t('Main front page'),
'access callback' => TRUE,
);
return $items;
}
function misite_theme() {
return array(
'main' => array
(
'template' => 'main',
'variables' => array('title' => NULL),
),
);
}
function main() {
$path = drupal_get_path('module', 'a');
$title = t('');
$build['mainelement'] = array(
'#theme' => 'main',
'#title' => $title,
);
$output = drupal_render($build);
return $output;
}
From the looks of this line:
$path = drupal_get_path('module', 'a');
Your module is called a.
In Drupal, the convention for hook naming is MODULE_NAME_name_of_hook() (see http://api.drupal.org/api/drupal/includes--module.inc/group/hooks/7).
This is true for both hook_menu() and hook_theme() so in your case if the module is called a your functions should be names a_menu() and a_theme().
If you make changes to any hooks make sure you clear Drupal's cache so the relevant registrys are updated.

migrating url alias from drupal6 to drupal7 as a part of migration process

I have migrated nodes using migrate module v2. Currently i am running into a problem that the previous site used url aliases,which have not been migrated into drupal7 and will affect the site rank from SEO perspective.
Is there a way i can migrate the path aliases while running the migration classes itself?If not what would be the best way to do so?
You can migrate your legacy aliases directly into the Drupal 7 path field:
$this->addFieldMapping('path', 'my_legacy_alias_field');
Here is a very stripped down migration class that includes an easy method for bringing URLs along for the ride. Intended for use with the Migrate module.
class MyNodeMigration extends Migration {
public function __construct(array $arguments) {
$this->arguments = $arguments;
parent::__construct();
$source_fields = array('nid' => t('The node ID of the page'));
$query = Database::getConnection('default', 'legacy')
->select('node', 'n')
->fields('n');
$query->join('url_alias', 'a', "a.src = CONCAT('node/', n.nid)");
$query->addField('a', 'dst');
$this->source = new MigrateSourceSQL($query, $source_fields);
$this->destination = new MigrateDestinationNode('my_node_type');
$this->map = new MigrateSQLMap($this->machineName,
array('nid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'description' => 'D6 Unique Node ID',
'alias' => 'n',
)),
MigrateDestinationNode::getKeySchema()
);
$this->addSimpleMappings(array('title', 'created', 'changed', 'status'));
$this->addUnmigratedDestinations(array('sticky', 'log', 'nid'));
$this->addFieldMapping('path', 'dst');
$this->addFieldMapping('is_new')->defaultValue(TRUE);
}
}
As I can see, the url_aliastable is globally the same, expect the name of fields whom changed from srcto sourceand dst to alias. So I guess you can easily copy the content from your Drupal 6 to your Drupal 7.
I never tried, but in theory it should work.
The best way (according to me) to have the same url aliases is :
1> install url_alias module.
2> configure the nodes with patterns similar to drupal6. Now, this step may trouble you, in case the new url-aliases have nids attached to them.(as in my case).
As a solution we can go ahead and create custom tokens using code where the source id can be fetched from the migrate map tables based on the new destination ids which are easily available.
Now, we can go ahead and bulk generate url-aliases.
An example for creating such custom token would be:
/**
* Implements hook_token_info().
*/
function custom_configuration_token_info() {
$type = array(
'node' => array (
'name' => t('Nodes'),
'description' => t('Tokens related to individual nodes.'),
'needs-data' => 'node',
),
'term' => array(
'name' => t('Taxonomy Terms'),
'description' => t('Tokens related to taxonomy terms.'),
'needs-data' => 'term',
)
);
// tokens for node legacy nid.
$tokens['node']['mapid'] = array(
'name' => t("mapid"),
'description' => t("The nid of the node prior to migration."),
);
$tokens['term']['mapid'] = array(
'name' => t('mapid'),
'description' => t('The tid of taxonomy terms prior to migration.'),
);
return array(
'types' => $type,
'tokens' => $tokens,
);
}
now,
function custom_configuration_tokens($type, $tokens, array $data = array(), array $options = array()) {
$url_options = array('absolute' => TRUE);
if (isset($options['language'])) {
$url_options['language'] = $options['language'];
$language_code = $options['language']->language;
}
else {
$language_code = NULL;
}
$sanitize = !empty($options['sanitize']);
$replacements = array();
if ($type == 'node' && !empty($data['node'])) {
$node = $data['node'];
foreach ($tokens as $name => $original) {
switch ($name) {
<write your custom code for the token conditioned by the name attribute in info function>
}
}
}
While writing your custom code, you mite also be needing the legacy table. Drupal 7 supports multiple databases, so just configure the legacy table credentials in settings.php file.
Use drupal_set_active while fetching data from the different tables.
Thanks.

Please Explain Drupal schema and drupal_write_record

1) Where is the best place to populate a new database table when a module is first installed, enabled? I need to go and get some data from an external source and want to do it transparently when the user installs/enables my custom module.
I create the schema in {mymodule}_schema(), do drupal_install_schema({tablename}); in hook_install. Then I try to populate the table in hook_enable using drupal_write_record.
I confirmed the table was created, I get no errors when hook_enable executes, but when I query the new table, I get no rows back--it's empty.
Here's one variation of the code I've tried:
/**
* Implementation of hook_schema()
*/
function ncbi_subsites_schema() {
// we know it's MYSQL, so no need to check
$schema['ncbi_subsites_sites'] = array(
'description' => 'The base table for subsites',
'fields' => array(
'site_id' => array(
'description' => 'Primary id for site',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
), // end site_id
'title' => array(
'description' => 'The title of the subsite',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
), //end title field
'url' => array(
'description' => 'The URL of the subsite in Production',
'type' => 'varchar',
'length' => 255,
'default' => '',
), //end url field
), //end fields
'unique keys' => array(
'site_id'=> array('site_id'),
'title' => array('title'),
), //end unique keys
'primary_key' => array('site_id'),
); // end schema
return $schema;
}
Here's hook_install:
function ncbi_subsites_install() {
drupal_install_schema('ncbi_subsites');
}
Here's hook_enable:
function ncbi_subsites_enable() {
drupal_get_schema('ncbi_subsites_site');
// my helper function to get data for table (not shown)
$subsites = ncbi_subsites_get_subsites();
foreach( $subsites as $name=>$attrs ) {
$record = new stdClass();
$record->title = $name;
$record->url = $attrs['homepage'];
drupal_write_record( 'ncbi_subsites_sites', $record );
}
}
Can someone tell me what I'm missing?
If ncbi_subsites_get_subsites() is not in the .install file, you need to include whatever file its in with your module. Otherwise, it's returning nothing, in which case try dumping $subsites and exiting.
I think the answer is that drupal_write_record is not meant for install or enable hooks. I think when enabling or installing, you have to write SQL. That is the impression I am getting from reading some posts that mention that the schema is not available in these hooks.
First of all (assuming Drupal 6), drupal_write_record() cannot be called from hook_install() because Drupal would not find the database schema defined from the module, which is still going to be installed, and enabled.
Instead you need to use db_query() function. (the comments are speaking of a way to include default data by prviding it to hook_schema() serialized, but i've found no documentation on this.)
However, would you be using (the development version of) Drupal 7, you want to look at the db_insert() function instead.

Resources