I've built an application to run on the client side (JavaScript & HTML) which needs to access and updated data on a server. It has a schema which consists of 5 tables. I've defined exactly what they should look like in JSON. I want these to be available as a JSON service served from a Drupal module. I understand how to use drupal_json_output to provide the results. I just can't find a simple way to ensure the database table is created for them and then to add and remove items from it. I'd like to maintain Drupal's independence from the underlying database. I don't need any search functionality, forms functionality etc. I just want to use Drupal's Database Abstraction.
At the moment I've tried the following in my install file:
/**
* Implements hook_schema
*/
function rcsarooms_schema(){
$schema = array();
$schema['rcsarooms'] = array(
'description' => 'Stores the structured information about the rooms and staircases.',
'fields' => array(
'ID' => array(
'type' => 'varchar',
'length' => 10,
'not null' => TRUE,
'description' => 'Primary Key: used in the URLs to identify the entity.'
),'Name' => array(
'type' => 'varchar',
'length' => 200,
'not null' => TRUE,
'description' => 'The name used for links in the navigation menues.'
),'ParentID' => array(
'type' => 'varchar',
'length' => 10,
'not null' => TRUE,
'description' => 'The ID of the parent element or "Root" if this is a root element'
),'Type' => array(
'type' => 'varchar',
'length' => 15,
'not null' => TRUE,
'description' => 'page, staircase, house, room or special'
),'BathroomSharing' => array(
'type' => 'int',
'description' => 'The number of people the bathroom is shared with (0 for unknown)'
),'RentBand' => array(
'type' => 'int',
'description' => 'The ID of the rent band the room is in.'
),'Floor' => array(
'type' => 'int',
'description' => 'The floor number (0 is courtyard level).'
)
),
'primary key' => array('ID')
);
return $schema;
}
And the following in my module file:
/**
* Implements hook_menu
*/
function rcsarooms_menu(){
$items['rcsarooms'] = array(
'page callback' => 'rcsarooms_callback',
'access callback' => TRUE,
'type' => MENU_CALLBACK
);
return $items;
}
function rcsarooms_callback(){
drupal_json_output(db_query("SELECT * FROM {rcsarooms}"));
drupal_exit();
return;
}
This gives the following error when I attempt to navigate to rcsarooms:
PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'db.rcsarooms' doesn't exist: SELECT * FROM {rcsarooms}; Array ( ) in rcsarooms_callback()
You're probably looking for hook_schema() which Drupal will use to create your custom tables when you install your module. It goes in the mymodule.install file.
The Schema API will tell you everything you need to know about data types etc.
For adding/removing items from the database use the db_insert(), db_update() and db_merge() functions
Related
Because of a long series of events, I thought I lost a site completely due to my hosting company losing a server. Anyway, I'm trying to get back into a site sitting on a server with a cpanel I cant get to and a WHM I cant get to. I only have access to the root dir via ftp. I was able to reset my admin password using the method here https://www.drupal.org/node/1556488
I meant to also clear the flood table, but deleted it instead with db_drop_table('flood');
So, now I am getting a MYSQL error when I try to login. So, given I only have access to running php scripts to interact with the SQL database, can anyone help me figure out how to rebuild the flood table via the drupal db_create_table() method?
Much appreciated! This has been a nightmare.
I was able to rebuild my flood table with a php file ran from the drupal install directory with this in it: Just type in the url mysite.com/myphpfile.php to run it.
<?php
define('DRUPAL_ROOT', getcwd());
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
require_once DRUPAL_ROOT . '/includes/password.inc';
$schema = array();
$schema['flood'] = array(
'fields' => array(
'fid' => array(
'type' => 'int',
'length' => 11,
'not null' => TRUE,
),
'event' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'default' => '',
),
'identifier' => array(
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
'timestamp' => array(
'type' => 'int',
'length' => 11,
'not null' => TRUE,
),
'expiration' => array(
'type' => 'int',
'length' => 11,
'not null' => TRUE,
),
),
'primary key' => array('fid'),
);
db_create_table('flood', $schema['flood']);
print "Done. Please delete this file immediately!";
drupal_exit();
?>
How can i add a new field in prestashop's back office?
Specific, i want to insert a text field in the BO: Orders->Statuses->Add New Order Status under the status name. Which files i have to modify in order to do that? Can anyone describes the full procedure?
Thanks
I am using Prestashop version 1.6.1.2 and added one text field using following steps. You need to make changes in core files. You have to add field in one table in database and do some changes in class and controller file.
Here are the steps to do the same. I have adde field 'my_custom_field'.
Add one field in order_state table
ALTER TABLE {YOUR_DB_PREFIX}order_state ADD my_custom_field VARCHAR(50) NOT NULL;
Change class file of order state. You need to define your field in file "classes/order/OrderState.php"
After code
public $deleted = 0;
add this code snipet
public $my_custom_field;
After code
'deleted' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
add this code snipet
'my_custom_field' => array('type' => self::TYPE_STRING),
open "controllers/admin/AdminStatusesController.php" file and do following changes
in function initOrderStatutsList()
after this code
'name' => array(
'title' => $this->l('Name'),
'width' => 'auto',
'color' => 'color'
),
add this code
'my_custom_field' => array(
'title' => $this->l('My Custom Field'),
'width' => 'auto',
),
in function renderForm()
after this code
array(
'type' => 'text',
'label' => $this->l('Status name'),
'name' => 'name',
'lang' => true,
'required' => true,
'hint' => array(
$this->l('Order status (e.g. \'Pending\').'),
$this->l('Invalid characters: numbers and').' !<>,;?=+()##"{}_$%:'
)
),
add this code
array(
'type' => 'text',
'label' => $this->l('My Custom field'),
'name' => 'my_custom_field',
),
Do changes suggested here. Hope this helps you :)
How can I store a file in a drupal entity? I have a plublic key to associate to an user so I have created an APIuser entity but I don't know what kind of field give to the public key property
function api_user_schema() {
$schema['api_user'] = array(
'description' => 'The base table for api_user.',
'fields' => array(
'id' => array(
'description' => 'The primary identifier for an artwork.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'public_key' => array(
'description' => 'The primary identifier for the public key.',
'type' => ???,
'unsigned' => TRUE,
'not null' => TRUE,
)
'created' => array(
'description' =>
'The Unix timestamp when the api_user was created.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'changed' => array(
'description' =>
'The Unix timestamp when the api_user was most recently saved.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
),
'unique keys' => array(
'id' => array('id')
),
'primary key' => array('id'),
);
return $schema;
}
What you've got there is the definition of a single database table; Drupal offers no layer on top of that for files, so if you want to store a file you'll have to do so manually.
The best example you can take is that of the core user entity. It defines the picture property, which is an ID referencing an entry in the file_managed table (incidentally this is how all permanent file storage is handled by Drupal core by default).
This is the schema definition for that db column (from user_schema()):
'picture' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'description' => "Foreign key: {file_managed}.fid of user's picture.",
)
Which is very similar to what your definition will need to look like.
From there, have a look at the user_account_form() function (which defines the form element for the picture property), and the user_validate_picture() function, which will show you how to perform the file upload, save the file in the file_managed table, and change the submitted value for the picture field to the relevant file ID (so that it automatically gets saved against the entity).
You'll mostly be replicating the code from those two functions so it won't be that tricky.
I am new to PyroCMS and am willing to build a Job Site wherein there'll be 2 main users namely, Employers and Job Seekers. In order to allow them to register on the site, I'm using the Streams API from PyroCMS to build the forms. These users will be part of 2 different modules namely the Employer module and the Job Seeker module.
In the details.php file, under the install() function, I want to create multiple streams(database tables). The following code helps us to add a stream:
$this->streams->streams->add_stream();
The following code then helps us to define the fields to be added to the stream:
$this->streams->fields->add_fields($fields);
My concern is how do I add multiple streams like the above ones and add fields to each of them? In other words, how would the syntax
$this->streams->fields->add_fields($fields);
know which stream to add the fields to?
Have a look at the Fields Driver documentation for the Streams API. Fields and streams are separate entities, with no required association between the two. When adding a field you can assign it to a stream like this:
$field = array(
'name' => 'Question',
'slug' => 'question',
'namespace' => 'streams_sample',
'type' => 'text',
'extra' => array('max_length' => 200),
'assign' => 'STREAM_SLUG_GOES_HERE',
'title_column' => true,
'required' => true,
'unique' => true
);
$this->streams->fields->add_field($field);
Or you can create the streams and fields separately, and then assign each field to a stream like this:
$this->streams->fields->assign_field('streams_sample', 'STREAM_SLUG_GOES_HERE', 'question', array('required' => true));
All this talk of fields and streams makes me want to go outside...
You can add multiple streams like this example.
// Add banners streams
if ( ! $this->streams->streams->add_stream(lang('banner:banners'), 'banners', 'banner', 'banner_', null)) return false;
// Add groups streams
if ( ! $this->streams->streams->add_stream(lang('banner:groups'), 'groups', 'banner', 'banner_', null)) return false;
// Add some fields
$fields = array(
// BANNERS
array(
'name' => 'Banner Title',
'slug' => 'banner_title',
'namespace' => 'banner',
'assign' => 'banners',
'type' => 'text',
'extra' => array('max_length' => 200),
'title_column' => true,
'required' => true,
'unique' => true
),
// GROUPS
array(
'name' => 'Group Title',
'slug' => 'group_title',
'namespace' => 'banner',
'assign' => 'groups',
'type' => 'text',
'extra' => array('max_length' => 200),
'title_column' => true,
'required' => true,
'unique' => true
)
);
$this->streams->fields->add_fields($fields);
I'm trying to make a simple custom field "field_book_year" for the new node type "synopsis_book".
I have wrote in .install file:
function synopsis_install() {
node_types_rebuild();
$types = node_type_get_types();
// In Drupal 7 you must explicitly add a "body" field when you create a custom content type,
// thus the call to node_add_body_field($types['newsletter']);.
node_add_body_field($types['synopsis_book']);
$body_instance = field_info_instance('node', 'body', 'synopsis_book');
$body_instance['type'] = 'text';
field_update_instance($body_instance);
field_create_field(array(
'field_name' => 'field_book_year',
'label' => t('Company posting the job listing'),
'type' => 'text',
'translatable' => TRUE,
)
);
field_create_instance(array(
'field_name' => 'field_book_year',
'label' => t('Company posting the job listing'),
'entity_type' => 'node',
'bundle' => 'synopsis_book',
'type' => 'text',
'widget' => array(
'type' => 'text_textfield',
),
'display' => array(
'example_node_list' => array(
'label' => t('Company posting the job listing'),
'type' => 'text',
),
),
'description' => 'Begin Date',
)
);
}
Then, I have in .module these functions:
function synopsis_node_info()
{$types = node_type_get_types();print_r($types);
return array(
'synopsis_author' => array('name' => t('Author'), 'base' => 'synopsis_author', 'description' => t('Author description, biography etc.'),
'has_body' => true, 'has_title' => true, /*'min_word_count' => 11,*/ 'help' => t('Enter blah-blah-blah'),
'title_label' => t('Author full name')
),
'synopsis_book' => array('name' => t('Book'), 'base' => 'synopsis_book', 'description' => t('Book description, synopsis etc.'),
'has_body' => true, 'has_title' => true, /*'min_word_count' => 11,*/ 'help' => t('Enter blah-blah-blah'),
'title_label' => t('Book title')
),
);
}
/**
* Implement hook_form() with the standard default form.
*/
function synopsis_book_form($node, $form_state) {
return node_content_form($node, $form_state);
}
/**
* Implements hook_validate().
*/
function synopsis_book_validate($node)
{
// Enforce a minimum character count of 2 on company names.
if (isset($node->field_book_year) &&
strlen($node->field_book_year['und'][0]['value']) < 2
) {
form_set_error('job_post_company',
t('The company name is too short. It must be atleast 2 characters.'),
$limit_validation_errors = NULL);
}
}
Not matter all I've written, the page of adding the Book looks like this! No 'field_book_year' field. There is even no body field
What am I doing wrong? Thank you.
I think the problem you're having is that hook_install is run when your module is installed, before the node type is created. So essentially you're trying to attach a field to a non-existant node type at that point.
The way I've always done this is to create the node type in hook_install before trying to attach the field (this is an example from a module that provides a testimonial content type):
// Make sure a testimonial content type doesn't already exist
if (!in_array('testimonial', node_type_get_names())) {
$type = array(
'type' => 'testimonial',
'name' => st('Testimonial'),
'base' => 'node_content',
'description' => st("Use <em>basic pages</em> for your static content, such as an 'About us' page."),
'custom' => 1,
'modified' => 1,
'locked' => 0,
'title_label' => 'Customer / Client Name'
);
$type = node_type_set_defaults($type);
node_type_save($type);
node_add_body_field($type);
}
// See if the testimonial date field exists
if (!field_info_field('field_testimonial_date')) {
field_create_field(array(
// Field info here
));
}
// If the date field is not attached, attach it
if (!field_info_instance('node', 'field_testimonial_date', 'testimonial')) {
field_create_instance(array(
// Field instance info here
));
}
If you look in the standard installation profile install file you'll see this is actually how the Drupal core performs this task, so I would expect it's the 'correct' way to do it.