Friday, 30 August 2013

SugarCRM Customization: Drop Down Fields

Looking to create a drop down field in SugarCRM?  

No problem.  Simply go to the customization Studio and add a new field of type "Drop Down," making sure to assign or create the appropriate drop down list at field creation time.

Simple enough, but that only works for custom fields.  What about changing an existing, default field so as to make it behave like a drop down.  For example, we might want to change the Subject field for Cases or the Name field for Opportunities into drop downs. 

Doing so would help us ensure uniformity in the classification of support inquiries or revenue opportunities, which in turn improves data quality and simplifies the measurement of effectiveness.  Ultimately, one of the goals of CRM technologies is to simplify the process of measuring how well your business is doing and the quality of the data in the system has a significant impact on that function.

So, how do we convert these default text fields to drop down fields?  Lets take a look.
Our first step is to determine if we need to define a new drop down list or if we are going to use an existing one.  

The drop down list contains the values that a user will be allowed to pick from for the field in question.  Note that the user must select a value from that list and will not be able to manually type in a random value.  As a result, the selected drop down list must contain appropriate values or we must create a new list that does.

We will assume we need to create new lists, respectively named 'cases_name_list' and 'opportunity_name_list.'  To create a new list, follow these steps:

1. Access SugarCRM as an admin level user.
2. Select Admin > Dropdown Editor
3. Click Add Dropdown

Proceed to name the list and enter the desired values.  Click Save when finished and repeat the process for the second list.

Now that the lists are ready, we need to connect them to the respective fields and instruct SugarCRM to make the fields behave like drop down fields.

To accomplish this, we need to do three things: create the PHP file with the instructions, place the file in the appropriate location within the SugarCRM install folder and lastly, execute a Repair operation within SugarCRM.

So what does the instruction file look like?  It is actually quite simple.  Create a file named vardefs.ext.php and add the following PHP code to it:

<?php
$dictionary['Case']['fields']['name']['type'] = 'enum';
$dictionary['Case']['fields']['name']['options'] = 'case_name_list';
?> 

That is all we need for the instructions.  

Now save the file and place it in the following folder: /custom/Extension/modules/Cases/Ext/Vardefs.  If the directory does not exist, proceed to manually create it via Windows Explorer or other similar tool appropriate for your operating system.  That completes the second step.  

To finalize the process, access SugarCRM using an admin level account and select Admin > Repair > Quick Repair and Rebuild.  

Take a look at the Cases module and the name field should now display as a drop down when in edit mode.

To complete the exercise and apply the modification to the Opportunities module, make another file named vardefs.ext.php, but with the following instructions:

<?php
$dictionary['Opportunity']['fields']['name']['type'] = 'enum';
$dictionary['Opportunity']['fields']['name']['options'] = 'opportunity_name_list';
?>

Place this version of the file in /custom/Extension/modules/Opportunities/Ext/Vardefs and rebuild!

To put value into   opportunity_name_list goto /custom/include/ and put the value there for the array of opportunity_name_list in associative array form.

Do the same for case_name_list.

Monday, 26 August 2013

import csv file in custom module of sugarcrm



Step1:


  File path


<application>/module/<module name>/module name.php

  
Add property below in class in above file
   
      var $importable = true;
   
note : But this is core class/file so think how to do in  your custom class. 

Step2:

  File path<application>/Extension/Module/<module name>/Ext/Menu/menu.php

 add code below
<?php

if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

if(ACLController::checkAccess('amit_test_amitesh_module', 'import', true)) $module_menu[]=Array("index.php?module=Import&action=Step1&import_module=amit_test_amitesh_module&return_module=amit_test_amitesh_module&return_action=index", "Import","Import", 'amit_test_amitesh_module');

?>


now you will get result.
hope u like it, thanks.


Thursday, 1 August 2013

Writing Drupal 7 Modules

Drupal is a powerful CMS right out of the box. But let's be honest. The real reason that Drupal has gained such traction in the crowded PHP CMS space isn't because it is loaded with bells and whistles, but because it can be extended in seemingly infinite ways through add-on modules. In fact, there are well over seven thousand modules available from Drupal.org. Why is it that Drupal enjoys such a wealth of user-contributed add-on code?
The answer is that Drupal's API (Application Programmer Interface) provides the golden combination of simplicity and power. Almost every phase of Drupal's page building process can be intercepted and the data modified. But powerful modules can still be written in just a few dozen lines of code.
In the next few pages we are going to create a module from scratch. We will build a module using the Block API – the system used to generate block content. The module we create in this article is going to provide a block that displays the number of members (user accounts) on the site.
This is how we will proceed:
  1. We will create a new module directory
  2. Then we will create a .info (dot-info) file to describe the module
  3. From here, we will create our basic .module (dot-module) file and introduce Drupal programming
  4. Next, we will create a couple of “block hooks” to define the behaviors of our new block
  5. Using the administration interface, we will turn on our new module and enable the block

Prerequisites

For this article, it is assumed that you have the following:
  • Basic PHP development knowledge
  • A running Drupal 7 instance with admin access
  • Access to the filesystem for your Drupal 7 instance
  • A code editor or PHP IDE
To get started, you will need a working Drupal 7 instance that you can access as an administrator. You will also need to be able to create files and directories inside of that Drupal installation. The examples in this article are done on a standard install of Drupal 7.0 with no contributed modules.

Creating a Module

Typically, a Drupal module has at least these three pieces:
  • A module directory that contains all module files
  • An information file
  • A module PHP code file
We will call our module membercount. In Drupal parlance, this name is called the machine name because it is the name Drupal (the machine) uses to reference the module.
Now that we have the machine name, we can create our module's directory. The default location for add-on modules is the sites/all/modules directory. In that directory, we will create a folder named with the module's machine name: membercount/.
Inside of this directory we will create two files. The first file, which we will see in the following section, will contain information about our module. The second one will contain the module's PHP source code.

The .info File

The first file in our module is the .info file. Drupal uses the .info file to determine details about the module, including whether the module can be installed and what other modules it depends upon. A .info file is always named with the machine name of the module, so our module must be named membercount.info.
The .info file contains a list of name/value pairs. This file isn't an ad hoc settings file where you can put any information that you wish. There are a dozen directives that can be placed inside of a module. We will be using only the few that are required.
name = Member Count
description = Provides a block that shows the number of members.
core = 7.x
The name directive is required in all .info files. Its purpose is to provide a human-readable name for the module.
The description directive should have a one-sentence description of what the module does.
The next directive, core, has a functional role. Drupal refers to this to make sure that the module can be installed. Attempting to install this module on a Drupal 6 system, for example, would generate an error.
All three of these directives are required.
To see all .info directives refer to http://drupal.org/node/542202.

Starting the .module File

The next file that we are going to create is the .module file, membercount.module. This file is automatically loaded by Drupal, which expects the file to contain PHP code. Like .info files, the base name of a .module file is the module's machine name.
For the most part, Drupal modules are written as procedural code. Typically, the preferred unit of organization for Drupal code is the function. Our module file will have a three functions in it. Here is the first:
<?php
/**
 * @file
 * The membercount module provides a block with member count information.
 */
 
/**
 * Implementation of hook_help().
 */
function membercount_help($path, $args) {
  if ($path == 'admin/help#membercount') {
    return t('To use this module, go to the block page and turn on the membercount block.');
  }
}
There are a couple things that I will note in passing, but which we don't have the space to examine more closely.
The first is the <?php processor instruction. This is required for any PHP files. Note, however, that there is no closing ?>. This is not only legal in PHP, but is considered a best practice for a file that is entirely source code. It prevents errors caused by premature buffer flushes.
The second thing is that it follows a very strict set of coding conventions. These conventions, described at http://drupal.org/node/360052, cover everything from indent depth (two spaces, no tabs) to naming conventions (lowercase with underscores), operators (one space on each side), and comment styles. Drupal developers are expected to follow these conventions in order to maximize the readability across the codebase.
The next thing of note is the use of documentation blocks. Documentation blocks are a special kind of comment that begins with /** and ends with */. The purpose of these sections is to provide source code documentation that can be extracted by automated tools. Every PHP file should have a file-level documentation block (which is flagged with the @file tag). Each function should also have a documentation block.
Now we are ready to look at the function declared in the file above. The membercount_help() function provides help text for the module. By declaring this help function as above it is now available to Drupal. If we were to install the module as it is and go visit the help page, we would be able to see this help text under the Member Count module.
Member Count module
Drupal has picked up our help function and integrated it into its help system. How did it do this?
This is where Drupal's cornerstone feature comes into play. Drupal uses a callback-like system called hooks. At strategic times during page processing, Drupal looks for any functions that follow a specific naming pattern (hook functions) and it invokes all matching functions. For example, when generating help text Drupal looks for anything that implements hook_help(). It then executes all of the matching functions, gathers the returned data, and displays the requested help page. To implement hook_help(), all we need to do is declare a function where the hook part of the name is replaced with our module's machine name: membercount_help().
Declare a function according to a predefined hook pattern and Drupal will just pick it up and use it. This is why Drupal is so easy to extend.
Of course there is a little more to it then that. You need to know what each hook invocation will give as input, and what output your hook is expected to return. In our example above, hook_help() implementations will get two arguments:
  • $path: The help path. A top level help screen will always get the path admin/help#MODULENAME.
  • $arg: Additional arguments passed in the URL.
The hook will be executed for any call to the help system, so it is up to us to determine whether the help call is one that we should answer. That is why the body of our help function looks like this:
if ($path == 'admin/help#membercount') {
  return t('To use this module, go to the block page and turn on the membercount block.');
}
In short, we only answer this request for help if the $path is set to 'admin/help#membercount'. In a more complex module we might have an entire help system where different paths contained information about different parts of the system.
Any request to hook_help() expects one of two things to be returned: a NULL value or a string of help text. While NULLs are ignored, strings are prepared and displayed. In practice, modules should have informative help text, but for the sake of illustration we have kept ours very short.
Notice that the string isn't simply returned. It's passed through the t() function. The t() function is primarily for translating strings into non-English languages. But t() performs other tasks as well. It can be used to insert values into strings (like the sprintf() family of functions) and to do some output filtering before data is sent to the client. The t() function is documented at http://api.drupal.org/api/drupal/includes--bootstrap.inc/function/t/7.

Five other Drupal functions you ought to know

The article introduces several important Drupal functions. Here are a few other commonly used Drupal functions.
  1. theme(): Pass data to the theme system for formatting
  2. l(): Transform a label and URI into a link
  3. module_invoke_all(): Execute a hook in all modules
  4. drupal_set_message(): Print a notice or error to the user
  5. watchdog(): Log a message to the Drupal log

Any string that contains output that is on its way to a user should be passed through the t() function. And this should happen when the string is declared. In other words, the following code is wrong:
$foo = 'This is my string.';
$bar = t($foo);
In order for the translation system to function correctly, t() should always be used like this:
$bar = t('This is my string.');
In the next section we are going to create a block.

Block Hooks

In Drupal, the block system is used for placing chunks of content around the periphery of the page. Blocks are administered through the Toolbar » Structure » Blocks page, where they can be positioned and configured.
Our module is going to provide a simple block that lists the number of accounts that exist on our site. To accomplish this, we are going to need to implement two hooks:
  • hook_block_info(): Tell Drupal about the block that we declare.
  • hook_block_view(): Answer a request to return a block's data.
There are other block hooks that we could implement, but for this example we can get by with just these two.
The first hook provides the information necessary to tell Drupal about all of the blocks that this module provides. Since our module only provides one block, our hook implementation is simple:
/**
 * Implements hook_block_info().
 */
function membercount_block_info() {
  $blocks = array();
 
  $blocks['count_members'] = array(
    'info' => t('Count Members'),
    'cache' => DRUPAL_NO_CACHE,
  );
 
  return $blocks;
}
This hook provides the settings for each block that the module declares. The block info hook takes no parameters and returns an associative array where the keys are the machine names of each block, and the values are an associative array of settings for each block.
Our module declares one block called count_members. And we are assigning it two settings:
  • info: This is required for every block. It should contain a short phrase describing the block. It is displayed only on block administration pages.
  • cache: This second flag uses one of the DRUPAL_ cache constants to tell Drupal whether it can cache the data, and if so, how it should cache the data. These flags are all documented at http://api.drupal.org/api/drupal/modules--block--block.api.php/function/.... We assign it the value DRUPAL_NO_CACHE, which tells Drupal not to cache the output of this block.
There are a few other possible settings, but these two are the ones typically used.
Now that we have provided this hook our block will be included in the list of available blocks. Next, we need to provide the content that our block will return by implementing hook_block_view().
/**
 * Implements hook_block_view().
 */
function membercount_block_view($name) {
 
  if ($name == 'count_members') {
    $count = db_query('SELECT COUNT(uid) - 1 FROM {users}')->fetchField();
 
    $content = format_plural($count, 'This site has 1 user.', 'This site has @count users.');
 
    $block = array(
      'subject' => t('Members'),
      'content' => $content,
    );
 
    return $block;
  }
}
Just as the hook_block_info() function was expected to produce block information for all blocks that the module declares, hook_block_view() is expected to produce the viewable content for any block that this module is responsible for. Thus, our block hook only responds when the name passed into the function matches the name we declared in the $blocks array in membercount_block_info().
Inside of the if statement our block function does four things:
  1. Query the database to find out how many users we have.
  2. Format the string to be returned.
  3. Create the block data structure (an associative array).
  4. Return the block.
      Our database query is simple:
      SELECT COUNT(uid) - 1 FROM {users}
      This selects the number of user IDs (minus one) from the users table. The users table is the main location for information about Drupal users. There is one record for each user of the system, plus one for the "anonymous" user. Since we don't want to include the anonymous account in our tally we subtract one.
      When writing SELECT queries in Drupal, the syntax used is a slightly modified SQL. Notice that in Drupal queries, table names are always surrounded with curly braces ({}). This is so that on hosts that have stricter naming conventions, database table name prefixing can be done without requiring a manual rewrite of all SQL statements. These and other details of Drupal database syntax are documented here: http://api.drupal.org/api/drupal/includes--database--database.inc/group/....
      The database query is executed using the db_query() function. It executes a simple query and returns an instance of a DatabaseStatementInterface. Since our query returned only one field (the results of the SQL COUNT()) we can use the fetchField() method to get the data for that single field.
      The next line of our block function takes the $count value and uses it to construct a string for display:
      $content = format_plural($count, 'This site has 1 user.', 'This site has @count users.');
      This line shows another interesting facet of Drupal's translation subsystem. Along with t(), Drupal provides other functions to handle translation difficulties. Human languages construct plurals in different ways. The pattern used in English is not the same as that in French, Hungarian, or Chinese. So strings that need to be translated differently depending on a number can be passed through the format_plural() function. In the default English case it will see if the $count value is 1. If so, it will use the first string (This site has 1 user). Otherwise it will use the second (plural) construction, substituting $count for the placeholder @count.
      The next thing to do is construct the data structure that Drupal is expecting this function to return: an associative array with two keys:
    • subject: The title of the block, which may be shown to the user.
    • content: The formatted body of the block.
    For our block, we set the subject to Members (and we pass it through t() for translation). The content is simply the $content variable. For a more complex block, we might use the theme() function to theme the data before setting it here. Finally, we return the block, allowing Drupal to continue assembling the blocks and rendering the page.

    Installing and Configuring Our Module

    We now have a complete module. Since we created it in sites/all/modules, installing it is a breeze. We can simply navigate to Toolbar » Modules and find it in the list:
    Module install
    Notice that the Name and Description columns pull their data from the membercount.info file we created earlier.
    Simply checking the box and clicking on the Save configuration button will enable our new module. It should then show up as enabled, and since we implemented hook_help(), we see a help icon in the right-hand column:
    Help icon
    Now we are ready to test out our module. Go to Toolbar » Structure » Blocks and position the block. Initially, there should be an entry named Count Members in the Disabled blocks list. We will put it in the Header section:
    Block screen
    Clicking Save blocks at the bottom of the page will save this change. Now we should be able to close the Administration overlay and see the results of our new block in the upper-right corner.
    Header output

    Conclusion

    We have created our first working Drupal 7 module. At this point, you've gotten a small dose of coding in Drupal, though we have barely scratched the surface of what can be done. There is virtually no part of Drupal's page rendering that you can't modify through Drupal's APIs. And most of the time, modifying Drupal is just a matter of declaring a new module and writing the right hooks.
    The module we have created here is as basic as they come. More complex modules may contain multiple PHP source files, JavaScript files, and even templates, CSS, and images. It is even possible to group several modules together to create larger bundles of related features.
    Ready to move on? There are plenty of resources out there to help you get going, and Drupal.org is a great place to start.
To create a basic page to Drupal 7:
  1. Log into your Drupal 7 Dashboard
  2. In the top menu, click Content
  3. Click the Add content link at the top of the page.
    drupal_content_1
  4. From here, select Basic page from the list of different content types.
    drupal_content_2
  5. Fill in the Title and Body, and also select a type of text format.
    Title Enter a title for you new page. In our testing we entered Our Test Page, but you could use anything that you would like, such as About Us.
    Body The body is the bulk of the content for this new page. If this was an About Us page, this would be were you would enter the information about yourself or your organization. In our example, we simply entered This is our test page.
    Text Format When selecting a text format, you have the following options:

    - Filtered HTML
    - Full HTML
    - Plain Text
    Underneath the drop down that contains these choices, you will see notes explaining the choice iteself. For example, you may see a notice telling you that the option you have selected does not allow any HTML tags. As you change your option, the notes underneath will change as well.
    drupal_content_3
  6. There are a few other options you can specify. To change any of these settings, click the appropriate link at the bottom of the basic page editor.

    Menu Settings
    If we don't click the checkbox for Provide a menu link, we won't be able to find our page (in this specific example).

    We have checked that box, and the following settings appear:
    Menu Link Title When this link appears in a menu, this will be the text that users can click on to get to this page.
    Description If a user mouses over this link, after a moment the description you type here will show.
    Parent Item Choose the parent item for this page. For example, if we later created a Company History page, we may want to file it underAbout Us, and we could do that here.
    Weight you can adjust the weight to change in which order this link will appear.
    Revision Information If you have multiple authors or if you just like keeping detailed notes, in the revision information section you can enter a description about the changes you are making to the page.
    URL Path Settings This option allows us to specify a custom url alias. For example, if we leave this option blank, the URL will look similar to:

    BLANK:
    http://domain.com/node/1

    ... if we enter a value here, such as about-this-site, the url will look like the following:
    http://domain.com/about-this-site 
    Comment Settings If you would like to change the commenting settings for this particular page, you can do so here. For example, if you don't want to allow anyone to post a comment, select the option for Closed - users cannot post comments.
    Authoring Information In this section, you can set custom details about both who wrote the article and when it was published.
    Publishing Option - Published: if you don't have this option selected, your page will not be active and will not show up on your website.
    - Promoted to front page: selecting this option will put this page on your site's front page (homepage)
    - Sticky at top of lists: as the name implies, if this page appears anywhere within your site with other pages in a list type format, this page will be situated towards the top of the page. 

    drupal_content_4
  7. Click Save once you have filled in all the desired information.

    Now, when you visit your site and click on the link you created in the menu (if you did create the menu item as we did above), you will see the page you just created!
    drupal_content_5

Content Types in Drupal 7

There can be different types of content you can write. The default installation of Drupal 7 includes the following two types of content:
  1. Articles
  2. Basic Pages
Articles Basic Pages
Articles in Drupal 7 can be thought of as news and announcements. This is content that you publish frequently, and the time or frequency that you publish the content is important. Basic pages in Drupal 7 is content that is more permanent, such as an About Us type page. Sure, you can edit your About Us page whenever you would like, but it is generally not a page that you would remove from your navigation, such as a news item. 
There are more content types that you can create in Drupal 7, but Articles and Basic Pages are the only ones that are ready for you to use right now. As we progress further into our Drupal 7 education channel, we'll cover other content types more in depth.
Now that we covered the basics on Articles vs. Basic Pages, let's now look into how to create them:
For more information on this course please visit Working with Content in Drupal 7.

Writing module .info files (Drupal 7.x)

Overview

Drupal uses .info files (aka, "dot info files") to store metadata about themes and modules.
For modules, the .info file is used for:
  • rendering information on the Drupal Web GUI administration pages;
  • providing criteria to control module activation and deactivation;
  • notifying Drupal about the existence of a module;
  • general administrative purposes in other contexts.
This .info file is required for the system to recognize the presence of a module.

Example

The following is a sample .info file:
name = Really Neat Widget
description = Provides a really neat widget for your site's sidebar.
core = 7.x
package = Views
dependencies[] = views
dependencies[] = panels
files[] = example.test
configure = admin/config/content/example
The .info file should have the same name as the .module file and reside in the same directory. For example, if your module is named example.module then your .info file should be named example.info.
This file is in standard .ini file format, which defines properties in key/value pairs separated by an equals sign (key = value). You may use quotation marks to wrap the value. Quoted values may contain newlines.
.info files may contain comments. A semi-colon [;] placed at the beginning of a line makes that line a comment, and that line will not be parsed.
Note: Whenever you create or change your .info file, you will need to clear your site's cache for your changes to take effect.

Properties

The .info file can contain the following properties:
name (Required)
This displays the name of your module, which will appear on the Modules page. Since module names are proper names, it should be capitalized as a proper name (e.g., "Really Neat Widget", not "really neat widget" or "Really neat widget"), and it should be a human-readable name (not really_neat_widget). If your module name includes an acronym (CSS, WYSIWYG, UI, etc.) or a third-party trade name (jQuery, JavaScript), of course follow the standard capitalization for those.
name = Really Neat Widget
description (Required)
A short, preferably one-line description that will tell the administrator what this module does on the module administration page. Remember, overly long descriptions can make this page difficult to work with, so please try to be concise. This field is limited to 255 characters.
description = Provides a really neat widget for your site's sidebar.
Descriptions can contain links to documentation and sources. The following example shows a link to the author. It could be a link to a documentation node on Drupal.org. This is useful when the online documentation is better than the readme file and when you want to read about a module before switching it on.
description = Domain manager by <a href="http://petermoulding.com">Peter Moulding .com</a>.
core (Required)
The version of Drupal that your module is for. For Drupal 7 this would be 7.x, etc. Note that modules cannot specify the minor version of a branch of Drupal. 6.x is correct; 6.2 is not.
core = 7.x
stylesheets (Optional)
Drupal 7 allows you to add CSS files in the module's .info file if it should be added on every page, just like theme .info files do. Here is an example from the node module's .info file:
stylesheets[all][] = node.css
scripts (Optional)
You can now add Javascript in the module's .info file if it should be added on every page. This allows Javascript to be aggregated in an optimal way, and is the preferred method of adding Javascript that most visitors will need on a typical site visit:
scripts[] = somescript.js
For more information see Managing JavaScript in Drupal 7.
files (Optional)
Drupal now supports a dynamic-loading code registry. To support it, all modules must now declare any code files containing class or interface declarations in the .info file, like so:
name = Really Neat Widget
...
files[] = example.test
When a module is enabled, Drupal will rescan all declared files and index all the classes and interfaces that it finds. Classes will be loaded automatically by PHP when they are first accessed.
dependencies (Optional)
An array of other modules that your module requires. If these modules are not present, your module cannot be enabled. If these modules are present but not enabled, the administrator will be prompted with a list of additional modules to enable and may choose to enable the required modules as well, or cancel at that point.

The string value of each dependency must be the module filename (excluding ".module") and should be written in lowercase like the examples below. Spaces are not allowed.
dependencies[] = taxonomy
dependencies[] = comment
In addition, test_dependencies[] can be used to indicate dependencies which are optional but recommended. At this writing they are supported only by Drupal.org's automated testing system. They cause the testbots to check out the projects suggested. Generally any modules that you have listed in the 'dependencies' array in the getInfo() function of your module's tests should be added as test_dependencies[].
test_dependencies[] = autoload
If you need to specify that a certain module's version number is required Drupal 7 provides a way for this in the dependencies[] field. Version numbers are optional and only necessary if the module absolutely requires another module's specific version or branch.
The syntax for the dependencies[] field(s) is:
dependencies[] = modulename (major.minor)
Where major is the numeric major version number and minor is the numeric or alphanumeric minor version number. x can be used to denote any minor version. Some examples follow.
name = Really Neat Widget
description = An example module
dependencies[] = exampleapi (1.x)

test_dependencies[] = autoload (>7.x-1.5)
...
In the above .info code, the "Example" module requires an "Example API" module with the major version of 1 and any minor version.
dependencies[] = exampleapi (1.0)
This means that the module requires the 1.0 (and only the 1.0) version of the Example API module.
dependencies[] = exampleapi (1.x)
The above module requires any minor version of the module in the 1.x branch (1.0, 1.1, 1.2-beta4, etc.)
The dependencies[] property in the .info file can also optionally specify versions:
  • = or == equals (optional: equals is the default)
  • > greater than
  • < lesser than
  • >= greater than or equal to
  • <= lesser than or equal to
  • != not equal to
dependencies[] = exampleapi (>1.0)
The above module requires any version greater than version 1.0.
You can optionally specify the core version number as well:
dependencies[] = exampleapi (>7.x-1.5)
The above module requires a 7.x version compatible version of the module and a version greater than 1.5.
Additionally, multiple version dependencies can be specified as comma-separated values within the parentheses:
dependencies[] = exampleapi (>1.0, <=3.2, !=3.0)
This facility can be used to specify a minimal core version by using system as the module name:
dependencies[] = system (>=7.53)
This makes the module require at least Drupal 7.53.
package (Optional)
If your module comes with other modules or is meant to be used exclusively with other modules, enter the name of the package here. If left blank, the module will be listed as 'Other'. In general, this property should only be used by large multi-module packages, or by modules meant to extend these packages, such as Fields, Views, Commerce, Organic Groups, and the like. All other modules should leave this blank. As a guideline, four or more modules that depend on each other (or all on a single module) make a good candidate for a package. Fewer probably do not. An exception to this rule is the "Development" package, which should be used for any modules which are code development tool modules.

If present, the package string groups modules together on the module administration page (admin/modules); the string should therefore be the heading you would like your modules to appear under, and it needs to be consistent (in spelling and capitalization) in all .info files in which it appears. It should not use punctuation and it should follow the Drupal capitalization standard as noted above.

Capitalization is important because package string is case sensitive, and using package = fields in one module and package = Fields in another would yield two different packages on the module administration page. This can be highly confusing as Seven (the default administrative theme) capitalizes fieldset legends, making fields and Fields indistinguishable. Using package = Fields is the correct way.
package = Views
Suggested examples of appropriate items for the package field:
  • Administration
  • Commerce
  • Development
  • Fields
  • Media
  • User interface
  • Views
  • Voting (if it uses/requires VotingAPI)
The Package names for contributed modules wiki tries to track current package names; this does not mean they are recommended.
php (Optional)
As of version 6.x, module and themes may specify a minimum PHP version that they require. They may do so by adding a line similar to the following to their .info file:
php = 5.3
That specifies that the module/theme will not work with a version of PHP earlier than 5.3. That is useful if the module makes use of features added in later versions of PHP (improved XML handling, object iterators, JSON, etc.). If no version is specified, it is assumed to be the same as the required PHP version for Drupal core. Modules should generally not specify a required version unless they specifically need a higher later version of PHP than is required by core. See the PHP Manual for further details on PHP version strings.
version (Discouraged)
The version string will be added by drupal.org when a release is created and a tarball packaged. However, if your module is not being hosted on the drupal.org infrastructure, you can give your module whatever version string makes sense.

Users getting their modules directly from git will not have a version string, since the .info files checked into git do not define a version. These users are encouraged to use the git deploy module to provide accurate version strings for the admin/build/modules page for modules in directories checked out directly from git.

Because Drupal core uses a slightly different packaging process than contributed modules, the core modules have a version line predefined. This is an exception to the rule, not the model for contributed modules.
configure (Optional)
As of version 7.x, the path of the module's (main) configuration page.
If a module is enabled, a "Configure" and "Permissions" link appear. This will be the path of the "Configure" link for this particular module on the modules overview page.
configure = admin/config/content/example
required (Optional)
As of version 7.x, modules and themes may specify that they are absolutely required and should never be disabled by adding required = TRUE. These modules will be enabled automatically during install. In most cases it should only be used with the Drupal core required modules (e.g. Node, User, etc.).
hidden (Optional)
As of version 7.x, modules and themes may specify that they should not be visible on the modules page by adding hidden = TRUE. This is commonly used with testing modules used with SimpleTest where end-users should never enable the testing modules.
project (Discouraged, packaging use only)
Module maintainers should not use this at all. The packaging script on drupal.org will automatically place a string here to identify what project the module came from. This is primarily for the Update status module, so that Drupal installations can monitor versions of installed packages and notify administrators when new versions are available.
project status url (Only used for custom modules not submitted to drupal.org)
Allows module maintainers to define a URL to check for updates to their module using the Update status module. No module released on drupal.org should define this parameter. URL should point to an XML feed that accepts requests in the form of http://my.domain.com/projects/{project}/{core}. In that example, project status url should be set to http://my.domain.com/projects.
For more information on info file formatting, see the drupal_parse_info_file() documentation.

Troubleshooting

I added the core = 7.x line, but my module still says "This version is incompatible with the 7.x version of Drupal core" on the modules page. What gives?
Be aware that the "dependencies" format changed between Drupal 5.x and 6.x.
Wrong:
name = Really Neat Widget
...
dependencies = foo bar   ; 5.x dependency format.
core = 6.x
Correct:
name = Really Neat Widget
...
; Note the [], and that each of the dependencies is on its own line:
dependencies[] = foo
dependencies[] = bar
core = 7.x

Description and Non-ASCII Characters

Note that if you want to use accented characters or other non-ASCII characters in your .info file's description field, you should include the HTML escaped notation, e.g., &ouml; for the "รถ" character or &copy; for the "©" character.