I'm using the Schema API to create tables for my module on Drupa 6.17, but the tables just do not get created in the database. I have the Schema module installed, and it tells me that while the schema for my module is recognized, its table is not in the database. It comes up under Missing:
Tables in the schema that are not present in the database.
test
* test_table
Here are the contents for my test.install file.
<?php
// $Id$
function test_schema() {
$schema['test_table'] = array(
'description' => t('Test table'),
'fields' => array(
'nid' => array(
'description' => t('test field'),
'type' => 'serial',
'not null' => TRUE,
),
'options' => array(
'description' => t('other test field'),
'type' => 'text',
'not null' => FALSE,
),
),
'primary key' => array('nid'),
);
return $schema;
}
function test_install() {
drupal_install_schema('test');
}
function test_uninstall() {
drupal_uninstall_schema('test');
}
if you want to add module install after the module creation you need to remove the record from system table in your drupal db, and then enable it again.
disable your module and save
goto 'system' table and find your module there
remove that record
enable your module and save
Edit:
Here is code I just wrote that works. Follow as example:
/**
* Implementation of hook_schema().
*/
function action_alert_schema() {
$schema['action_alert'] = array(
'description' => 'Action Alert table.',
'fields' => array(
'aid' => array(
'description' => 'The serial ID.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'nid' => array(
'description' => 'The primary identifier of the node.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'uuid' => array(
'description' => 'The session id of the user if the UID is not present.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '0',
),
),
'primary key' => array('aid'),
);
return $schema;
}
/**
* Implementation of hook_install().
*/
function action_alert_install() {
drupal_install_schema('action_alert');
}
/**
* Implementation of hook_uninstall().
*/
function action_alert_uninstall() {
drupal_uninstall_schema('action_alert');
}
Drupal only runs a module's hook_install() once when you first enable the module. Unless you go through and disable, uninstall, and then re-enable the module will your module's hook_install() get called ever again.
If you had already created a release of your module and are wanting to add a schema to existing installs, you will want to add an implementation of hook_update_N() that calls db_create_table().
I would like to share with you my experiences with this error on Drupal 6. In my first-ever module I had three tables. I had an entry for each in my hook_schema (called education_schema):
function education_schema()
{
$schema['education_course'] = array( /* ... */ );
$schema['education_market'] = array( /* ... */ );
$schema['education_event'] = array( /* ... */ );
}
In my hook_install, I initially had the following:
function education_install()
{
drupal_install_schema('education_course');
drupal_install_schema('education_market');
drupal_install_schema('education_event');
}
No tables were creating at module install. Why? I had no idea: no errors to be seen anywhere in the logs. Eventually I found out about the PHP extension xdebug, which, when used in education_install revealed that drupal_install_schema failed because it could not find the routines education_course_schema, education_course_market and education_course_event. At that point the solution was quite obvious:
function education_install()
{
drupal_install_schema('education');
}
And voila, it worked!
So, I learned that drupal_install_schema does not log any error when it fails, that only one call to drupal_install_schema is required and that it installs all schemas that you return in the array, that the API documentation of drupal_install_schema is worth reading, and finally that xdebug is a very handy utility!
Related
I have a custom module on my site. I try to install an update with a new field for my vocabulary, but the field doesn't appear.
hook_update:
function mymodule_update_7118()
{
$field_name = 'field_newfield';
if ( field_info_field( $field_name ) ) {
return;
}
$field = array(
'field_name' => $field_name,
'type' => 'list_integer',
'settings' => array(
'allowed_values' => array(
'Yes' => 1, //heard that adding a NO value may cause problems, although it doesn't work with a no value either.
),
),
);
$field = field_create_field( $field );
$instance = array(
'field_name' => $field['field_name'],
'entity_type' => 'taxonomy',
'bundle' => 'vocab_name',
'label' => 'Label',
'widget' => array(
'active' => 1,
'module' => 'options',
'settings' => array(),
'type' => 'options_select',
'weight' => '3',
),
);
field_create_instance($instance);
}
Logs contain several recordings of Internalization module creating a string to translate this field. Also all needed tables are created in the database, but they are all empty.
For creating a new custom field you must do it like a custom module. The steps can be found out at https://drupal.stackexchange.com/questions/140517/how-to-create-new-field-type
You can find the excellent field_example module from the Examples Module which is always the first place to look. Examples module can be downloaded from https://www.drupal.org/project/examples
i have created module but unablet to create table below is my code of mysubscribers.install
mysubscribers.install
function mysubscribers_schema(){
$schema['mysubscribers'] = array(
'description' => 'The table for storing the subscriber data.',
'fields' => array(
'id' => array(
'description' => 'The primary identifier for subscriber.',
'type' => 'serial',
'not null' => TRUE,
'unsigned' => TRUE,
),
),
'primary key' => array('id'),
);
return $schema;
}
/**
* Implements hook_install().
*/
function mysubscribers_install() {
if (db_table_exists('mysubscribers')) {
db_drop_table('mysubscribers'); // old table from 5.x-2.x
}
}
No issues here when running your code.
You don't need to remove the DB on install.
If you make changes to the schema add your changes to hook_update()
with something like db_change_field() or db_add_field().
As long as your naming convention is correct this should work.
assuming you have a mysubscribers.info,mysubscribers.module, and mysubscribers.install
I have a problem with the EWZRecaptcha Bunlde (dev-master) and symfony 2.1.0.
The reCaptcha is displayed correctly and the image changes so i think the configuration is ok. But the reCaptcha is not validated and after submitting, $form->getErrorsAsString() says: This form should not contain extra fields.
Well, i think the extra fields are recaptcha_challenge_field and recaptcha_response_field that are sent from reCaptcha but i don think that i missed something in the docu so what can be wrong with them?
For validation i use the code from the docu: (i also tried the alternative, that was mentioned there)
use EWZ\Bundle\RecaptchaBundle\Validator\Constraints as Recaptcha;
//...
/**
* #Recaptcha\True
*/
public $recaptcha;
//...
in config:
framework:
validation: { enable_annotations: true }
i added the field like this:
$builder->add('recaptcha', 'ewz_recaptcha', array(
'property_path' => false,
'attr' => array(
'options' => array(
'theme' => 'clean'
)
)
));
Maybe i forgot something essential, that was not mentioned in the docu?
Possibly try adding a 'constraints' option to the builder. My recaptcha builder add looks like this:
$builder->add('recaptcha', 'ewz_recaptcha', array(
'attr' => array(
'options' => array(
'theme' => 'red'
)
),
'label' => "Verification",
'property_path' => false,
'constraints' => array(
new True()
),
'help' => "Enter the words in the box for verification purposes."
));
So add a 'use' statement for the constraint:
use EWZ\Bundle\RecaptchaBundle\Validator\Constraints\True;
and then add the constraint option:
'constraints' => array(
new True()
),
finally found the solution!
to get rid of the extra fields i added those two fields in my form class:
$builder->add('recaptcha_challenge_field', 'hidden', array('property_path' => false));
$builder->add('recaptcha_response_field', 'hidden', array('property_path' => false));
the validation then works with:
use EWZ\Bundle\RecaptchaBundle\Validator\Constraints\True;
...
'constraints' => array(
new True()
)
the annotation doesn`t work for me:
use EWZ\Bundle\RecaptchaBundle\Validator\Constraints AS Recaptcha;
...
/**
* #Recaptcha\True
*/
public $recaptcha;
I am trying to convert my module from drupal6 to drupal 7 this is my code. The database table is not created.
function example_install() {
drupal_install_schema('example');
}
/**
* Implements hook_schema().
*/
function example_schema() {
$schema['example'] = array(
'description' => 'example settings',
'fields' => array(
'name' => array(
'description' => 'name',
'type' => 'varchar',
'length' => '255',
'not null' => TRUE,
),
'age' => array(
'description' => 'age',
'type' => 'int',
'size' => 'tiny',
'not null' => TRUE,
),
) ,
);
return $schema;
}
Can any one explain whats wrong.
You don't want to run drupal_install_schema() yourself in Drupal 7, hook_schema() is called automatically if it exists in the .install file. That will probably cause a few problems but you'd still expect the table to be created at least once.
Once you've removed hook_install() try uninstalling (not just disabling) your module, then re-enabling it. I recommend the Devel module to do this as it provides a page (devel/reinstall) where you can easily force a reinstall of a module.
If you don't want to do that though, go to the modules page, disable the module, then click the 'Uninstall' tab at the top to uninstall it fully. Then go back to the modules page and re-enable it.
Doing this should force Drupal to re-run your hook_schema() script and the table should be created.
Is it possible to declare and manage several custom content types inside one module? I'm creating a site that needs four custom content types and I'd like to manage them from one module instead of creating module for every content type. After some testing, I found out that it seems impossible. Because, unless hook_form and content type share the same name of module, drupal doesn't call hook_form.
Here's how I'd like to do -
function mycontent_node_info(){
return array(
'mycontent1' => array(
'name' => t('....'),
'module' => 'mycontent',
'description' => t('...),
'has_title' => TRUE,
'title_label' => t('Title'),
'has_body' => TRUE,
'body_label' => t('content body'),
),
'mycontent2' => array(
.......
),
'mycontent3' => array(
......
),
'mycontent4' => array(
......
),
);
}
function mycontent1_form(&$node){
$form['control1'] = array(
'#type' => 'select',
'#options' => array(
'0' => t('selection 1'),
'1' => t('selection 2'),
),
'#attributes' => array('id'=>'control1'),
);
$form['control2'] = array(
'#type' => 'select',
'#options' => array(
'0' => t('1'),
'1' => t('2'),
'2' => t('3'),
'3' => t('4'),
),
'#attributes' => array('id'=>'control2'),
);
return $form;
}
function mycontent2_form(&$node){
....
}
function mycontent3_form(&$node){
....
}
function mycontent4_form(&$node){
....
}
Am I doing something wrong here or is not possible and there's no alternative other than creating module for every content types. I appreciate much your help.
The prefix for all your hooks should be the name of your module, i.e. mycontent_node_info() and mycontent_form(&$node). I think the content type itself can be called whatever you want but by convention anything global that you define in a module should be prefixed with the name of the module to avoid namespace problems. So your content becomes mycontent_type1, mycontent_type2, etc... As for dealing with hook_form, I guess the way to do it is to check the type of the node passed in and act accordingly.
You might try using the Features module (http://drupal.org/project/features) to export your content types. It auto generates the code to make this work, and you can have a look at what is going wrong with your code.