Showing posts with label Drupal7. Show all posts
Showing posts with label Drupal7. Show all posts

Saturday, December 14, 2013

Getting drush to work ( on flexwebhosting ) fixing "exec() has been disabled for security reasons" and "This configuration is incompatible with drush."

I run in a bit of trouble installing drush on a new webhost.
I just started following the tutorial on drupal.org:
Specific instructions for installing Drush on different platforms
Since I'm using CentOS I picked the Install Drush on CentOS (with H-Sphere)
But then when I tried to run drush after install I got some errors.
The first one I got was: "exec() has been disabled for security reasons"
After I fixed that one I got:
"The following restricted PHP modes have non-empty values: [error] disable_functions. This configuration is incompatible with drush."

Both errors can be fixed by putting this in the command line on the server:
# mkdir -p ~/.drush
# cp -i /usr/local/lib/php.ini ~/.drush/
# nano ~/.drush/php.ini

Then find the "disable_functions" string and make it is empty:
disable_functions =
save the php.ini file and drush should be working now :)

source articles:
https://drupal.org/node/2009426
http://ventraip.com.au/forums/index.php?/topic/5394-drush-phpini-and-exec/
http://www.6by9.net/drush-on-an-hosting-fix-using-custom-php-ini/

Friday, July 12, 2013

Alter view and pager to display more items per page programmatically

I have 1 codebase for a multisite install. I needed to change the number of items per page on every page and didn't want to use the view ui and change every view. So I looked for a way to do this programmatically.

As it turns out this is quite simple.

I used hook_views_pre_build() to do this:

/**
 * Implements hook_views_pre_build ()
 */
function MODULENAME_views_pre_build(&$view) {
  if($view->name == "name_of_your_view") {
    $view->items_per_page = 30;
  }
}

Friday, June 21, 2013

Create one time login link from the command line using drush no need to reset your password

I don't use this command as much but when I need it I always forget what this string of code was.

So I'll post it on my blog :)

The magic:
drush uli

Or if your targeting a specific user:
drush uli username

Using drush you can create a one time login link for a user or admin.
This is especially usefull if you want to login to the site without changing the password.
For example if you have a client with a drupal site that doesn't know the administrators pass or doesn't want to change it because you need it.
This can also be used to change the password if you don't know where the password reset link would be send or don't have access to the email address ( anymore )

Wednesday, June 19, 2013

Creating a link field programmatically for a profile2 user entity and deleting it upon disable or uninstall

In this example I have a profile2 profile called "werkgever"

The field I'm creating is a field used for that profile to input a website link.

required modules are
link
profile2

My module name is more_werkgever_fields

Using hook_enable I create the field:
/**
 * Implementation of hook_enable().
 */
function more_werkgever_fields_enable() {
  // Check if our field is not already created and if not create the field.
  if (!field_info_field('field_website')) {
    $field = array(
        'field_name' => 'field_website',
        'type' => 'link_field', // text
    );
    field_create_field($field);

    // Create the instance on the bundle.
    $instance = array(
      'field_name' => 'field_website',
      'entity_type' => 'profile2',
      'label' => 'Website',
      'bundle' => 'werkgever',
      'required' => FALSE, // default: FALSE
      'settings' => array(
         // Here you inform either or not you want this field showing up on the registration form.
        'user_register_form' => 1,
      ),
      // 'widget' => array(
      //   'type' => 'link',
      // ),
    );
    field_create_instance($instance);
  }
}

This needs to be put in your modulename.install file

Also in the .install file you can implement a hook_disable or hook_uninstall
hook_disable is called when you disable the module. So this is handy if you are in a developing stage.
Just disable de module and your field should be gone.
An implementation of hook_disable:
/**
 * Implements hook_disable
 */
function more_werkgever_fields_disable(){
  // removes field when module is disabled
  field_delete_field('field_website');
}
As said this goes into your module.install file as well
Finally there is the Implementation of hook_uninstall:
/**
 * Implements hook_uninstall
 */
function more_werkgever_fields_uninstall(){
  field_delete_field('field_website'); // removes field from the system
}
The uninstall hook is only called upon uninstalling the module. I recommend putting your delete field in here. Or don't delete your field. Depending if your your module can be reused by others and maybe causing problems if that field is to be deleted. In my case I don't want it to clutter my database so I put it in my uninstall hook.

Monday, October 29, 2012

Setting a different default theme by default in an install profile

For an install profile you can look at the profiles that are included in the drupal install.
They can be found in sitename/profiles
As in an standard Drupal 7 instal there are 2 profiles 'minimal' and 'standard'.

The profiles are somewhat like modules and also work like that.

The profilname.info file can be used to define dependencies and thus enabling the defined modules when this profile is chosen.
again look at the standard.info file for an example.

In the .profile file you can alter the form that is used upon install and predefine values for fields.

but to set an other default theme you need the .install file.

In the .install file you place an hook_install()

at the end of your profilename_install() hook you place the following code:
profilename_install() {
// some other code

  db_update('system')
    ->fields(array('status' => 1))
    ->condition('type', 'theme')
    ->condition('name', 'yourthemename')
    ->execute();
  variable_set('theme_default', 'yourthemename');
}
Just make sure that yourthemename is available in your install directory.


Setting the theme settings.

The next step is setting the theme variables but I haven't figured that out so I will update this post when I get there...

I think you can set the values in the 'system' table WHERE `name` = 'themename'
Best way to do this is click the theme to the point you like it, then go to the database and copy the values of the according `info` field.

Friday, October 26, 2012

adding a city autotagging field to an user by creating a custom drupal 7 module

This posts tells you about how to programmatically create a field, instance, taxonomy library and create an autotagging widget in the form with it.

First in your module.install file create a hook_enable() function.
In the final version this would be hook_install() but while testing the module I find it easier to use hook enable so you can do: drush en mymodule -y and drush dis my module -y to enable and disable the module.

My module is called popover so that's the name I'll be using next.


/**
 * Implements hook_enable
 * runs every time this module is enabled, to run only at install use hook_install
 * Once the module has been enabled ( even only once ) hook_install won't be called anymore.
 */
function popover_enable() {
        // starting with the taxonomy library ( vocabulary ) first:

$vocabulary = (object) array(
'name' => 'City',
'description' => 'Pick your city :)',
'machine_name' => 'city',
);
taxonomy_vocabulary_save($vocabulary);
$terms = array(
'Amsterdam',
'Rotterdam',
'Rosmalen',
'Driebergen',
'Zeist',
'Utrecht',
);
        // I've created a custom function to save multiple terms to one vocabulary:
_popover_taxonomy_terms_save($terms,$vocabulary->vid);

        // building the field
$field = array(
'field_name' => 'field_' .$vocabulary->machine_name,
'type' => 'taxonomy_term_reference',
'settings' => array(
'allowed_values' => array(
array(
'vocabulary' => $vocabulary->machine_name,
'parent' => 0,
),
),
),
);
field_create_field($field);

        // connecting the user to the field I've just created
$instance = array(
'field_name' => 'field_' . $vocabulary->machine_name,
'entity_type' => 'user',
'label' => $vocabulary->name,
'bundle' => 'user',
'required' => TRUE,
'widget' => array(
'type' => 'taxonomy_autocomplete',
'weight' => -4,
),
'display' => array(
'default' => array(
'type' => 'taxonomy_term_reference_link',
'weight' => 10,
),
'teaser' => array(
'type' => 'taxonomy_term_reference_link',
'weight' => 10,
),
),
);
        // another custom field creator function
popover_field_create_update_instance($instance);
}



And the function I'm calling from the code above:

/**
 * save multiple terms to one taxonomy Vocabulary
 * @param  array $terms array of term names
 * @param  int   $vid   Vocabulary id
 */
function _popover_taxonomy_terms_save($terms,$vid) {
foreach($terms as $term) {
taxonomy_term_save(
(object) array(
'name' => $term,
'vid' => $vid,
)
);
}
}

/**
 * field creater helper function checks if field already is in this bundle if so do update instead of create
 */
function popover_field_create_update_instance($instance) {
if( field_info_instance($instance['entity_type'], $instance['field_name'], $instance['bundle']) == NULL) {
return field_create_instance($instance);
}
else{
return field_update_instance($instance);
}
}



Now because the instance is in the user bundle the field should now be showing up on the user edit form.

To delete the instance, field and vocabulary upon uninstall of the module. I've written the following:


/**
 * Implements hook_disable()
 * TODO: needs to be hook_uninstall in the future but again for testing using the hook_disable
 */
function popover_disable() {
// create array with instances/fields/vocabularies to cleanup
  $cleanups = array(
  'city',
  // you can add more fields here...
  );
  foreach($cleanups as $name) {
  _popover_cleanup_instance_field_vocabulary($name);
  }

  // force field purge ( so it is really deleted without waiting for cron )
  // I think I would remove this in the final version as well since your not going to uninstall a
  // module and then reinstall it again immediately after. besides opening the module page 
  // and then the unistall page calls cron if I remember correctly but not sure about that... anyway:
field_purge_batch(5000); // not sure if this is a to high number...
}

/**
 * cleanup helper function
 * @param  String $name machine_name of the vocabulary ( 'field_' is added for the field/instance)
 */
function _popover_cleanup_instance_field_vocabulary($name) {
$instance = field_info_instance('user','field_' . $name,'user');
// removing instance of field_$name in the user bundle
field_delete_instance($instance, true);
// deleting field
field_delete_field('field_' . $name);

// delete city vocabulary
$vid = db_select('taxonomy_vocabulary', 'v')
    ->fields('v', array('vid'))
    ->condition("v.machine_name", $name)
    ->execute()
 ->fetchField();
  taxonomy_vocabulary_delete($vid);
}

You can see the whole module on my github But I'm still working on it so don't expect it to work 100%

Thursday, October 11, 2012

drush make with install profile run from github

keeping installing sites and enabling all those modules you use every time is a pain in the ass.

Well no more!

I discovered that there is an easier way!

To work with this you need to have a basic drupal webserver running or need to install that first.
also drush 5.x needs to be enabled so you can run drush make

To get a quick and dirty solution just for testing or for me to remember how to get the install, you need to run the following command in the folder where you want the drupal install:
drush make https://raw.github.com/scubafly/drupal-make-files/master/d7.make -y

To jump to understanding what I did, here's what I did:

First I made a list of modules that I always use.
Then based on that list I created a .make file which now sits at https://raw.github.com/scubafly/drupal-make-files/master/d7.make 

And looks like this:
core = 7.x
api = 2

; core
projects[] = drupal
; basic drupal 7 install always needed file with devel included
projects[] = admin_menu
projects[] = ctools
projects[] = devel
projects[] = link
projects[] = mail_logger
projects[] = l10n_client
projects[] = l10n_update
projects[] = backup_migrate
projects[] = entity
projects[] = module_filter
projects[] = pathauto
projects[] = profile2
projects[] = token
projects[] = taxonomy_csv
projects[] = wysiwyg
projects[] = views

So now I can run the following command in the terminal while sitting in the folder where I want my drupal install:
drush make https://raw.github.com/scubafly/drupal-make-files/master/d7.make -y
This will download the latest drupal 7 and modules that where included in the make file.

So yeah thats all fun and all, but still you need to click trough the install and use "drush en module, module, module, module" or manually click to enable all the modules you want for every install.

Creating a profile.

The easiest way to create a profile from scratch is to copy the profile from an existing drupal install.
The install profiles can be found in websitefolder/profiles/<profilename>

profiles are somewhat like modules except they are not, they are profiles :)
Now in the .info file you can define which modules should be enabled. If you look at the standard profile ( websitefolder/profiles/standard/standard.info ) you can see that there are dependencies defined.
for example this is how you would define that devel should be enabled upon installation:
dependencies[] = devel

More information how to create profiles can be found here

I've pushed the profile into github so I can include it in my make file. My profile info looks like this at the moment of writing:
name = Jack standaard
description = basic install profile
core = 7.x

;this is used to enable the modules

; d7.make modules
dependencies[] = admin_devel
dependencies[] = admin_menu
dependencies[] = ctools
dependencies[] = block
dependencies[] = color
dependencies[] = contextual
dependencies[] = dashboard
dependencies[] = dblog
dependencies[] = field
dependencies[] = field_sql_storage
dependencies[] = field_ui
dependencies[] = file
dependencies[] = filter
dependencies[] = help
dependencies[] = image
dependencies[] = list
dependencies[] = locale
dependencies[] = menu
dependencies[] = node
dependencies[] = number
dependencies[] = options
dependencies[] = overlay
dependencies[] = path
dependencies[] = rdf
dependencies[] = search
dependencies[] = shortcut
dependencies[] = system
dependencies[] = taxonomy
dependencies[] = text
dependencies[] = trigger
dependencies[] = update
dependencies[] = user
dependencies[] = devel
dependencies[] = link
dependencies[] = mail_logger
dependencies[] = l10n_client
dependencies[] = l10n_update
dependencies[] = backup_migrate
dependencies[] = entity
dependencies[] = module_filter
dependencies[] = pathauto
dependencies[] = profile2
dependencies[] = token
dependencies[] = taxonomy_csv
dependencies[] = wysiwyg
dependencies[] = views
dependencies[] = views_ui


Since I pushed the whole profile to github ( click the link for details ) I can now include the profile to the make file which then ends up looking like this:

core = 7.x
api = 2

; core
projects[] = drupal
; basic drupal 7 install always needed file with devel included
projects[] = admin_menu
projects[] = ctools
projects[] = devel
projects[] = link
projects[] = mail_logger
projects[] = l10n_client
projects[] = l10n_update
projects[] = backup_migrate
projects[] = entity
projects[] = module_filter
projects[] = pathauto
projects[] = profile2
projects[] = token
projects[] = taxonomy_csv
projects[] = wysiwyg
projects[] = views

; add custom profile
projects[jack_standaard][type] = "profile"
projects[jack_standaard][download][type] = "git"
projects[jack_standaard][download][url] = "git://github.com/scubafly/jack_standaard.git"

make sure u use the git read only link as url that works the best without the need of logging in.

now when you run drush make https://raw.github.com/scubafly/drupal-make-files/master/d7.make -y  the drupal, the modules and the profile will be downloaded. And when you open the webpage you should see the 'jack_standaard' profile as option to install.




Wednesday, October 10, 2012

Create a new repository and add ssh login for the command line so you don't have to type your password every time you do a git push


Create a new repository and add ssh login for the command line so you don't have to type your password every time you do a git push

1) Create new repository on github
2) Create a new repository on the command line


touch README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin git@github.com:scubafly/<reponame>.git
git push -u origin master


To create a new ssh rya key pair if needed see https://help.github.com/articles/generating-ssh-keys

after that you can use the following to log in once per terminal without reentering the username and pass all the time...

In the terminal enter:
3) ssh-agent bash
4) ssh-add
5) enter passphrase

Monday, October 8, 2012

Adding a submit function without changing the current

I created a custom table in the database for my module and would like to save a field to that database upon submit of the user_profile_form.

I did this by creating a custom submit handler using the hook_form_alter() function
But instead of just changing the $form['submit'] I added a submit handler as first value of the $form['submit'] array like so:
array_unshift($form['#submit'], 'job_agent_user_profile_form_submit');

Resulting in the following function:

/**
 * Implements hook_form_alter()
 */
function job_agent_form_alter(&$form, $form_state, $form_id) {
if($form_id == 'user_profile_form') {
// get job agent value from db for user that is being edited
$account = $form_state['user'];
$job_agent = db_select('job_agent_searches', 'j')
->fields('j',array('enabled'))
->condition('uid', $account->uid)
->execute()
->fetchField();

// add extra field job agent field to the form
$form['job_agent'] = array(
'#title' => t('Job Agent'),
'#type' => 'checkbox',
// table: job_agent_searches field: enabled where uid = uid
'#default_value' => $job_agent,
'#description' => t('zet hier je job agent op basis van jouw profiel aan of uit.')
);
// add submit handler 'on top' of submit array instead of overwriting it leaving other submit functions there to work as well.
array_unshift($form['#submit'], 'job_agent_user_profile_form_submit');
}
return $form;
}

And finally create the custom submit handler function:

/**
 * Custom submit handler to be added to user_profile_form
 * saves job_agent field to job_agent database for the user that is being edited.
 */
function job_agent_user_profile_form_submit($form, &$form_state) {
$account = $form_state['user'];
// save job agent field to the db here.
db_update('job_agent_searches')
->condition('uid', $account->uid)
->expression('enabled',':enabled', array(':enabled' => $form_state['values']['job_agent']))
->execute();
}