Friday 7 October 2016

JQuery on a form that sends to submit once all the fields are filled out


                              // All sections have been filled out
                // After this we'll then reveal the next section.

                $("#edit-field-supplier-email-und-0-email").focusout(function(e){
                    // has all fields got data in.  If so lets move on
                    if ( $("#edit-field-supplier-email-und-0-email").val() != '' && $("#edit-field-company-name-und-0-value").val() != '' && $("#edit-field-phone-number-und-0-value").val() != '' && $("#edit-field-post-code-und-0-value").val() != '' && $("#edit-field-supplier-email-und-0-email").val() != ''){

                        // prefill postion placing
                        $("#edit-field-position-reached-und-0-value").val(1);

                        $("#supplier-node-form").submit();

                    }

                });


Wednesday 7 September 2016

JQuery to check a Checkbox is filled out and then add a class to the parent Div.

I had a bit of a struggle with this simple bit of code. And that was because examples I'd found hadn't include the use of .each !!

Here's a couple of searches I'd made - 'javascript checkbox value checked then add class to parent' , 'jquery onload' and 'jquery check an object with no action'

The code that worked for me is as such

 

$("input[type=checkbox], input[type=radio]").each(function(){
                    console.log('loading checkbox object');
                    // is(':checked')
                    if($(this).is(':checked')){
                        $(this).parent().addClass("chked");
                        $(this).parent().parent().addClass("chked");
                    }
                });

Thursday 1 September 2016

Drupal 7 Form API displaying only the Parent options in an Entity / Content Field item

So what I have is a Content Form where I want to display a Term / Taxonomy but only the Parent items for the moment.

Here's a way of solving this programmatically in a Hook Form Alter.

In my hook_form_FORM_ID_alter I iterate through the options array and remove the child choices. This is easy as those choices start with a minus sign .

  foreach ($form['my_field']['und']['#options'] as $key => $value) {
   // if $value starts with '-' then its a child item and I'll unset it.
    if ($value[0] == '-'){
      unset($form['my_field']['und']['#options'][$key]);
    }

  }

Tuesday 2 August 2016

OpenOffice and how to count Yes's in a column ( or any string )

Click on Sum and use something like this

=COUNTIF(A2:A100000;"=yes")

Tuesday 26 July 2016

Drupal 7 - Extending Push Notification Extended

The following is an extension to Push Notifications module in Drupal 7 to pass through extra data with the Payload.

This module is currently for testing purposes and can be called through the URL call to notifications/send_extend/%

Where % is the User Id of the user we'll be sending the notification to.

The change to the Payload array is in push_notifications_send_alert_extended .

Super Administration and Administration are the only roles allowed to visit the above link.

Module -> push_notifications_extend

push_notifications_extend.info

name = Push Notifications Extend
description = A module for extending the Push Notifications Module
core = 7.x
dependencies[] = push_notifications


push_notifications_extend.module

 'Send APNS Notifications',
    'page callback' => 'push_notifications_extend_manual_send',
    'access callback' => 'push_notifications_extend_send_access',
    'type' => MENU_CALLBACK,
  );

  return $items;
}


function push_notifications_extend_manual_send() {

  $user_to_send_to = arg(2);

  $users_to_notify[] = $user_to_send_to;

  $return = "

Sending push notification to " . count($users_to_notify) . " user.

"; push_notifications_extend_send_message($users_to_notify); variable_set("user_queue", 0); variable_set("apns_sent", 0); return $return; } function push_notifications_extend_send_message($users) { $unix_timestamp = microtime(); $watchdog_msg = 'Sending test message to ' . count($users) . ' user - at ' . $unix_timestamp; $message = "Test - Log Ref : $unix_timestamp"; push_notifications_send_message_extended($users, $message); } /** * Access callback for users to send APNS. * * @return bool */ function push_notifications_extend_send_access() { global $user; $access = FALSE; if (in_array('Super Admin', $user->roles) || in_array('administrator', $user->roles)) { $access = TRUE; } return $access; } /** * Send a simple message alert to an array of recipients. * * @param array $recipients Array of user ids. * @param string $message Message to be included in payload. * @return mixed Flag to indicate if delivery was successful. */ function push_notifications_send_message_extended($recipients, $message) { // Shorten the message characters / 8 bit. $message = truncate_utf8($message, PUSH_NOTIFICATIONS_APNS_PAYLOAD_SIZE_LIMIT, TRUE, TRUE); // Convert the payload into the correct format for delivery. $payload = array('alert' => $message); $tokens = array(); foreach ($recipients as $uid) { $user_tokens = push_notification_get_user_tokens($uid); if (!empty($user_tokens)) { $tokens = array_merge($tokens, $user_tokens); } } // Stop right here if none of these users have any tokens. if (empty($tokens)) { return FALSE; } // Send a simple alert message. push_notifications_send_alert_extended($tokens, $payload); } /** * Handle delivery of simple alert message. * * @param array $tokens Array of token record objects. * @param array $payload Payload. * */ function push_notifications_send_alert_extended($tokens = array(), $payload = array()) { // Group tokens into types. $tokens_ios = array(); $tokens_android = array(); foreach ($tokens as $token) { switch ($token->type) { case PUSH_NOTIFICATIONS_TYPE_ID_IOS: $tokens_ios[] = $token->token; break; case PUSH_NOTIFICATIONS_TYPE_ID_ANDROID: $tokens_android[] = $token->token; break; } } // Send payload to iOS recipients. if (!empty($tokens_ios)) { // Convert the payload into the correct format for APNS. $payload_apns = array('aps' => $payload, 'acme' => 'foo'); push_notifications_apns_send_message($tokens_ios, $payload_apns); } // Send payload to Android recipients if configured correctly. if (!empty($tokens_android) && ((PUSH_NOTIFICATIONS_C2DM_USERNAME && PUSH_NOTIFICATIONS_C2DM_PASSWORD) || PUSH_NOTIFICATIONS_GCM_API_KEY)) { // Determine which method to use for Google push notifications. switch (PUSH_NOTIFICATIONS_GOOGLE_TYPE) { case PUSH_NOTIFICATIONS_GOOGLE_TYPE_C2DM: push_notifications_c2dm_send_message($tokens_android, $payload); break; case PUSH_NOTIFICATIONS_GOOGLE_TYPE_GCM: push_notifications_gcm_send_message($tokens_android, $payload); break; } } }

Friday 22 July 2016

Drupal 7 changing links of the fly in a Drupal Menu

This is a bit of hack but I thought I’d get it documented here anyway. Please for feel free to message me with better solutions for sorting this issue.

The reason you can’t do this with hook_menu_alter is that this method does not create the menu on the fly; as the menu is built and stored in cache.

Here in my code I’ve got a calculation that returns a NID that I want to replace with the default one that I have in the menu item.

So I’ve added this to the body class list and retrieve it in the Javascript.

/*
 * Implements hook_preprocess_html()

 */

function MODULE_preprocess_html(&$variables){

  global $user;

  drupal_add_js(drupal_get_path('module', 'MODULE') . '/js/MODULE.menu.overrides.js');

// the method here calculates what Nid I need to direct what user too. 
    $getNid = SupplierFormHelpers::getNid($user->uid);

    $variables['classes_array'][] = 'ROLE-logged-in';
    $variables['classes_array'][] = $getNid;

  }

}



and here's the Javascript file

/**
 * @file
 * Javascript to replace NID with the one for the current User
 */
(function ($) {

    /**
     * Process controls.
     */
    Drupal.behaviors.moduleMenuOverrides = {

        attach: function (context) {

            // first of all lets place the number somewhere ( body class !! ) and retrieve that .

            if ($("body").hasClass("ROLE-logged-in")){

                var pageNid = 1;

               /* get the body class array and retrieve the next number along */
                var classList = $("body").attr('class').split(/\s+/);

                for (var i = 0; i < classList.length; i++) {
                    if (classList[i] === 'ROLE-logged-in') {
                        var i2 = i + 1;
                        pageNid = classList[i2];
                    }
                }

                /* i now have the number I want to replace with - so let's do a swap */
                
                var editLink = '/node/' + pageNid + '/edit';
                var navigation = $("#block-system-navigation");
                $("#block-system-navigation").each(function(){
                    var html = $(this).html();
                    html = html.replace("/node/1/edit", roleLink);
                    $(this).html(html);

                })

            }

        }
    }

})(jQuery);

Wednesday 20 July 2016

Drupal 7 form API trying to use 'commerce_price' type .

I couldn't find a solution to this. Similar to the question raised here.

http://drupal.stackexchange.com/questions/127864/custom-form-adding-a-commerce-price-field

But I adopted another angle of how to display my form which I think is worth listing. As the form I wanted my user to see is pretty much the same as the one I already had in Admin for the entity then I changed the permissions for the front end users Roles to be able to see and edit the form.

I then used Pathauto to change the URL of the path, as the former path had '/admin/structure' at the beginning which I wasn't happy with.

And finally to add and process some other areas of the form that I wanted to was to user 'hook_form_FORM_ID_alter'



So if you searching for things like

drupal 7 Price with currency widget for form

drupal 7 form api example of '#type' => 'commerce_price',

Then maybe you to like me where barking up the wrong tree !!

Tuesday 19 July 2016

Drupal 7 : How to make an editable Content page that displays depending on the User : Part 1

This is a conceptual note making for this task . Part 2 will be the concise instructions on how to do this.


What I want to do is display some editable content to a User .


> Created a Page in Page Manager
> using the path /profile/edit
> in context selected ‘Node Edit Form’
> Set the Node ID - I’ll need to set this programmatically depending on the User that I’m logged in as
> Save
> now in Content when clicking on the ‘cog’ image on the top left of the pane you’ll be able to select from a ‘FORM’ tab that will have all the fields and buttons you’ll need to display the form .

Next up is to write a programmatical solution for changing the Profile content depending on the User and Role I have logged in.

Wednesday 13 July 2016

OpenOffice : Delete an apostrophe before numbers in cells

I've been having an issue with some data and processing it. On checking I notice that some cells have an apostrophe before the data .

I found how to Find and Replace then in this post https://forum.openoffice.org/en/forum/viewtopic.php?f=9&t=49046

1. Highlight all of the cells and use Format -> Cells to change the cell format to an appropriate number format.
2. With all of the cells still selected, go to the menu Edit -> Find & Replace
3. In the Search For box enter .* (period asterisk)
4. In the Replace with box enter &
5. Select More Options and check Current Selection Only and Regular Expressions
6. Click Replace All

Monday 11 July 2016

Drupal 7 : How to Create and Save data to Entities ( in a formAPI )

Here’s a code sample of how I’ve saved to an Entity using EntityMetaDataWrapper . I’ve included on how you’d save a Taxonomy as well as a text field.
All of this code I’ve put in the ‘_submit’ function of the Form . You could create the entity in the hook_form and then pass this through the $form_state although I’ve decided not to here.

Let's create the Entity . Where you see 'marquee' this is the Entity name and the 'type' is the bundle.

 
$pricing = entity_create('marquee', array('type' =>'pricing'));

We then use this entity to create our MetaDataWrapper - The documentation for entity_metadata_wrapper gives the first argument to be passed in as $type. Which is slightly confusing as above 'type' is the bundle, here its the Entity type for example 'node', 'user', 'file' or a custom type .

$wrapper = entity_metadata_wrapper('marquee', $pricing);

You can then prepare the Entity's data like this
$wrapper->title->set('My title);

To get a list of all the fields that you have in the entity to set you can use the Field Map function .

$a_look_at_the_field_map = field_info_field_map();

No need to leave this line in though as it's just so you can add a breakpoint and check other all your entity maps.

From here you'll be able to check what you can set in your entity. To set a field with a taxonomy it's a easy as
$wrapper->field_type_size->set($sizes_tid);

With text fields that hold more than one piece of data then you'll need to fill each cell . For example we have a carpet price that also needs a currency code set with it. So here I needed to add both bits of data .

$wrapper->field_base_price->amount->set($base_price);
$wrapper->field_base_price->currency_code->set('USD');
If you're wondering how I worked out that I needed to user 'field_base_price->amount->set' and 'field_base_price->currency_code→set' . Well I got those from the database . I checked the database table 'field_data_field_base_price' and in here we have the columns 'field_base_price_amount' and 'field_base_price_currency_code' - if you ignore the 'field_base_price_' part of the name that will give you the directions for where to make these value changes.

All that's left is to Save and leave a success message .

$wrapper->save();
 
drupal_set_message(t('Success'));

Friday 8 July 2016

How to Use Classes in Your Drupal 7 Custom Module

I’ve had a couple of issues with this the last time I’ve set it up from scratch. Normally I’m coming into a project to make changes and not starting from scratch.

The one thing I’d been missing though is that you need to install a ‘Autoload’ into Drupal 7 . This is core in Drupal 8 Install ‘X Autoload’ - https://www.drupal.org/project/xautoload
Enable
In your module create a new folder . i.e. ‘src’
Create and name a file in that Folder. Use camel case and make it self explanatory

For example MyUsefulHelper.php

**
 * @file
 * Contains MyUsefulHelper
 */
 
namespace Drupal\MY_MODULE;
 
 
class MyUsefulHelper {
 
// Methods go here
 
}


Note that in the case of 'src' you do not need to name that in the Namespace .
And then in your .module file use code like.

use Drupal\supplier_form\TaxonomyHelpers;

From here on you should be able to call on the methods in the class.

Thursday 7 July 2016

Drupal 7 - Some useful FormAPI notes

Here's some instruction on how to make a Basic Form with a Menu Link -
https://www.drupal.org/node/1419390

Attached is a basic Hello World version demonstrating this .

How to use Ajax to display, hide or change Fields.

Say for example you have a drop down selection and you'd like it so that a choice here effects the next selections that you may take.

What you need to do is add an 'Ajax Event' to the form field . Take this for an example


$form['shop_select'] = array(
  '#type' => 'select',
  '#title' => t('Selected'),
  '#options' => array(
    0 => t('Fruit'),
    1 => t('Veg'),
  ),
  '#ajax' => array(
    'event' => 'change',
    'wrapper' => 'type-wrapper',
    'callback' => 'type_ajax_callback',
    'method' => 'replace',
  ),
  '#default_value' => 0,
  '#description' => t('Select what your looking for.'),
);


This will be added to the form in hook_form or hook_form_alter .

Following this we'll no need to set up the wrapper that's being called in '#ajax' . Note: make sure this is an 'id' in the div. Using 'class' will not work .

$form['type-wrapper'] = array('#prefix' => '
', '#suffix' => '
');

After this , still in hook_form you can write the code that will change the form to how you want it on the conditions you want. First off I'm checking what the current value in the first dropdown is

$shop_select = isset($form_state['values']['shop_select']) ? $form_state['values']['shop_select'] : 0;

I've made the default here '0' . Next I add another dropdown depending on that result.
switch ($shop_select) {
  case 0:
    // Set default options.
    $form['type-wrapper']['sizes'] = array(
      '#type' => 'select',
      '#title' => t('Sizes'),
      '#options' => array(
        0 => t('Size 1'),
        1 => t('Size 2'),
      ),
    );
    break;
  case 1:
    // Set up case 2
    $form['type-wrapper']['sizes'] = array(
      '#type' => 'select',
      '#title' => t('Sizes'),
      '#options' => array(
        2 => t('Size 3'),
        3 => t('Size 4'),
      ),
    );
    break;
}

Lastly in the 'ajax' call we set up a callback function. We use this to tell our code to only refresh that part of the form that we want it to

function sizes_ajax_callback($form, $form_state) {
   return $form['type-wrapper'];
}

Thursday 2 June 2016

How to fix a Drupal 7 a $hashed_pass not matching user_pass_rehash issue

With some code that does the check for the one-time log in link I had an issue with the $hashed_pass not matching the user_pass_rehash that I was running for the check . Here's how solved this issue. 1. Breakpointed all calls to user_pass_rehash 2. I then noticed that the $user->login was being entered in as zero on the first call. 3. Fixed this issue.

Tuesday 24 May 2016

Drupal 7 - issue sending Attachments with hook_mail

If you're having issue with sending Attachments then here's how I solved the issue.  There are other ways but this is how I solved the issue when it wasn't working.


Install these modules 
  1.  Mail System - https://www.drupal.org/project/mailsystem
  2.  Swift Mailer - https://www.drupal.org/project/swiftmailer
You'll also need to install the Swift Mailer library this is done through Composer
 composer require swiftmailer/swiftmailer

Enable the above modules. 
Then you'll need to add the following to your $message array.
 


//File to Attach - this uses Swift Mail to attach the file.
      $file_to_attach = new stdClass();
      $file_to_attach->uri = 'sites/default/files/report.csv';
      $file_to_attach->filename = 'report.csv';
      $file_to_attach->filemime = 'text/csv';

      $message['params']['files'][] = $file_to_attach;

Saving an array to CSV - Drupal 7 and other CMS's


After searching around for how to save an array as a CSV I made this method in one of my classes.

 I'm posting this a blog as it seemed a bit cleaner than many of the snippets and examples I'de seen.

 Check http://php.net/manual/en/function.fputcsv.php  for documentation if you need to write your own.

public function createCsv($list, $uri) {

  $file = fopen($uri, "w");

  foreach ($list as $line) {

    fputcsv($file, explode(',', $line));

  }

  fclose($file);

}


Pass this an array of a format like

$reportArray = [];

$reportArray[] = "Date, Offer, Count";

$reportArray[] = "01/01/1970, Free Sky, 1";

}


You can then call up with

  DailySummaryEmail::createCsv($csv_data_array, "public://folder/filename.csv");

Thursday 31 March 2016

Drupal 7 settings.php $conf error message - Use of undefined constant * - assumed '*' in include_once

The error here was

'Use of undefined constant site_name - assumed 'site_name' in include_once'


All I needed to do was to add quotes around my array element.

$conf[site_name]


to

$conf["site_name"]

Monday 21 March 2016

Drupal 7 - Mac Os - Mamp Fatal error: require_once(): Failed opening required ‘*’ (include_path='.:/Applications/MAMP/bin/php/php5.5.22/lib/php') in *includes/bootstrap.inc on line 3211

I needed to rebuild the registry and had a 'Bus 10' error with the 'Registry Rebuild' that's listed in modules.

To solve this on index.php add at the bottom


registry_rebuild
();


This is fine for fixing on local but if you're doing this on local but if you need to do it on a server a much better solution is to use the module https://www.drupal.org/project/registry_rebuild

And then

$ drush registry-rebuild
Just as a foot note I also got this message


Fatal error: Call to undefined function video_embed_field_property_info_callback() in */profiles/commons/modules/contrib/entity/modules/field.info.inc on line 30


To fix this I had to install the Video Embed Field Module and enable from drush.





Friday 18 March 2016

Acquia Offending RSA key in */.ssh/known_hosts:5 Message

When trying to run a drush command I got the following error.

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
*
Please contact your system administrator.
Add correct host key in *.ssh/known_hosts to get rid of this message.
Offending RSA key in *.ssh/known_hosts:5
RSA host key for * has changed and you have requested strict checking.
Host key verification failed.


More than likely it's just been a change on the server and nothing to panic about. 

If you remove the file ‘known_hosts’ from  >Users>you>.ssh   folder , the next time you run a command you'll get to choose whether to add to your know host list .

Tuesday 15 March 2016

Drupal 7 webform output country name instead of country code in webform country list


Drupal 7 webform output county name webform country list

What I have is the Country Codes being sent in emails where I want the country names.  This is using the module 'Webform Country List'
I feel like I should have been able to solve this with the module https://www.drupal.org/search/site/address%20field%20token  but couldn't get that to work.  If anyone knows how this is done then please let me know. 

So I've created a module that will do this for you and can be found at Drupal 7 Webform Country Token Names 

The code in this module is reliant on the fact the fieldname is 'country'  - if it isn't you'll either need to change the field name or customise this code.

How to turn on the Search ( Module Filter ) on the Module Page.

I'd made a hand full of searches and not been able to find the answer I wanted. - like


drupal 7 turn on module search


drupal 7 search module not working


What I needed to search for though was 'drupal 7 module filter '


Either install from https://www.drupal.org/search/site/module%20filter  or like I did enable on the Modules page. 

Thursday 10 March 2016

Mac Os Mavericks : How to download file without wget .

On a recent tutorial I was asked to install PHP Unit with wget.  To which I got this message

'-bash: wget: command not found'

Rather than installing this you can use 'curl'  .  Here's the commands I used.

'curl https://phar.phpunit.de/phpunit.phar -o phpunit.phar'

And then followed the next instructions the same as after 'wget'


'chmod +x phpunit.phar'

'mv phpunit.phar /usr/local/bin/phpunit'

Monday 7 March 2016

Some notes for Github Basics by Treehouse Course - commands for setting up profile, pages and joining other projects




How to create Personal pages. 

git status
git add . 
git commit -m “initial commit”
git remote add origin https://github.com/deejayM/djmillward.github.io.git
git push origin master


How to create Site pages

git checkout -b gh-pages
git add . 
git commit -m “Initial commit”
git remote add origin https://github.com/realkdaigle/simple-todo.git
git push origin origin gh-pages 


How to fix a Bug on .  

> In a git repository we’d need to make a ‘Fork’ in the repository

> first get a copy of the fork repository on your local environment.  

> git clone REMOTESITEADDRESS 

> the cd into the folder that’s just been created. 

> git checkout -b fix-treehouse-bug

> now to fix the bug .  lets open the file using vim

‘vim start.rb’

> Fix issue

> save file

> ‘git add .’

> Add commit message

> git push origin fix-treehouse-bug’

> Now we’ll need to make that Pull request. 

> hit the ‘Compare and Pull Request’ button. 

> Dev forks creates a branch and then submits a Pull request. 

> include unit tests

Friday 4 March 2016

Drupal 7 - Sql-sync Database from local project to Remote on Acquia.

Here's a couple of links that may be helpful.

http://drushcommands.com/drush-6x/sql/sql-sync/

and

https://www.acquia.com/gb/blog/use-drush-sync-your-drupal-installations-between-multiple-environments

First you need to be in your sites folder in terminal .

And the

drush sql-sync @self @YOURREMOTEALIAS



you can get your aliases with 'drush sa'

Thursday 3 March 2016

Some Treehouse notes.

Some notes I have on https://teamtreehouse.com/library/github-basics/working-on-a-team/working-on-a-team-review


Q: After merging a pull request, you want to look at the complete project history of changes. From a repository's main page, what tab will you click on?

A: commits

Q: When pulling down a branch for review, what's the correct set of Git commands?
A: git fetch git checkout

Q: In a new pull request, you're adding checkout functionality to your store application. What's the best Pull Request title for that change?
A: add checkout functionality to store

Q: If you're a member of the "acme" organization and want to team mention the "video" team, what's the correct format for the team mention?

A: acme/video

Some useful Drupal 7 module for when using Views to making Large Reports.

Here's a handful of useful Views Modules you should consider before taking on this task.  Before I start that list we also used a lot of customised code in a module for this project, which I'll go into in another blog.   When I started out on this task I had a fair bit of calculation being worked out in the template overrides.  This works but the calculations are being done in the wrong layer ( think MVC ) .  So custom View handlers and classes need to be made.

Anyway for the meantime here's some tools that have been used for this task .


First off let's here's a tool we've got in our locker that we can use from Drupal .

Global: Math : This is a field you can choose - with this field you can use values from any tokens used in prior fields to make basic calculations.

Views Lite Pager - https://www.drupal.org/project/views_litepager - pagination that uses less processing power of your SQL as the default Drupal pagination uses a COUNT query that can be painfully slow .
Login Trackerdrupal.org/project/login_trackerTracks each user and a historical data of their logins. This data is then exposed to view. 


View Field View [https://www.drupal.org/project/views_field_view]-    This module you allows you to embed a View as a field.   You’ll need a Caching method for this as well like ‘Views Content cache’ or ‘Cache Actions’ .  I used the former in our current project .

Lets take a look at an example of where this can be used.  Lets take the Login Tracker for example .  Lets say with have a report with an complex set of relationships .  Each row of information has an ‘Organisation’ as its core ‘FROM’ table. Rather than add another relationship here and possible another set of filter conditions ( i.e. date ) we could user View Field View and send over the Organisation Id as a condition.   Then we can add a relationship to User from the Company ; we can the access the field for ‘Tracker: Login timestamp’ -  And with aggregate functionality turned on we can take a count of this. 

Views Filter Field [ https://www.drupal.org/project/views_filterfield ] - Display exposed filter values as field in your view.

If for example youre using the View Field View module and you have a start and end date set as an exposed filter for your users.  You will want to send through in the condition the start and end date ; so that in your sub view you can the filter according to the user logins for that company in that date range.   

However we did need to make a tweak to this for this module as if the date range isnt selected.  

The change is to the field handlers . 

To do this we can extend the field handler class for this module which we have in /sites/all/modules/contrib/views_filterfield/handlers/views_filterfield.inc  - which itself extends the views_handler_field'

Youll need to put this new class in a custom module of your own .  Weve got all ours in Custom module called reports and the folders are arranged like this. 

Reports /
               admin_views_defualt /
               includes/
               src/
                              Controller /
                              Plugin / 
                              Reports/
                              SqlQueries/
                              Views/
                              Wrappers/
               theme/       
         
At this point it you havent worked with classes before Id need to go into more depth into namespacing and organisation but dont want to get too sidetracked.  So youll have to find this out yourself it youre not sure. 

In the class extension of views_filterfield make the change to render the default dates correctly as theyve been rendered into a sub-array.  

We do a check to see if our filter is indeed empty.  And 

We then go and get the value we want to fill it with and put that in the output.  Unfortunately its not quite that straight forward as we also need to create a load of create_function calls to fill the array where needed.  

Heres the code 


/**

 * @file

 * Contains Drupal\siaf_report\Views\Filter\DateFilterFieldFilter.

 *

 * The only purpose for extending these filters is to handle dates correctly;

 * by default they don't work because they've been rendered into a sub-array.

 */



namespace Drupal\siaf_report\Views\Filter;



use views_filterfield;



class DateFilterFieldFilter extends views_filterfield {



  function render($values) {

    $output = ['all'];



    $filter = $this->get_filter($this->options['views_filterfield_field']);



    // BEGIN CHANGES

    if (!empty($this->view->exposed_input[$filter['expose']['identifier']]['value'])) {

      if (is_array($this->view->exposed_input[$filter['expose']['identifier']]['value'])) {

        $output = $this->view->exposed_input[$filter['expose']['identifier']]['value'];

      }

      else {

        // Turn a single value into an array, so the transform array_walk

        // function works.

        $output = [$this->view->exposed_input[$filter['expose']['identifier']]['value']];

      }

    }

    // END CHANGES



    // Lots of create_function() calls next, as array_walk does not generally

    // play nice with internal functions, as it passes too many args. These

    // will simply throw a warning and not work.

    // @see http://php.net/manual/en/function.array-walk.php



    // Transform spaces to dashes.

    if (!empty($options['views_filterfield_transform_dash'])) {

      array_walk($output, create_function('&$val', '$val = strtr($val, array(" " => "-"));'));

    }



    // Transform case as needed by walking the array of values.

    switch ($this->options['views_filterfield_case']) {

      case 1: // Lower case.

        array_walk($output, create_function('&$val', '$val = drupal_strtolower($val);'));

        break;



      case 2: // Title case.

        array_walk($output, create_function('&$val', '$val = ucwords($val);'));

        break;



      case 3: // Upper case.

        array_walk($output, create_function('&$val', '$val = drupal_strtoupper($val);'));

        break;



      case 4: // Sentence case.

        array_walk($output, create_function('&$val', '$val = drupal_ucfirst($val);'));

        break;

    }



    // Turn the transformed array values into a delimited string.

    $separator = $this->options['views_filterfield_separator'];

    $output = implode($separator, $output);



    // Do some basic sanity checking. We don't want crazy values, do we?

    $checked = filter_xss($output);

    return $checked;

  }



}



Wednesday 2 March 2016

Some Git Hub Course notes .

For the Team Tree House Course >  Git Hub Basics 


Each project you have under version control will have a repository, which is a collection of commits describing the changes your project as you work. 

Git is a  distributed version control system, which means that there is no "central" repository for any given project; everyone has their own copy of the project repository that they can work with directly.


Which of the following sets of tools does a version control system provide?

Tools for exploring your projects history.

Git was created in large part to help manage what software project ?

the Linus kernel


The act of finalizing a change in version control is called "committing.”


In version control parlance, what is a repository?

The repository is where all of the version control information about a project is stored. 


The version control system you should use for any given project is going to depend a lot on your personal preferences and the preferences of the team you work with.


Git commands can be divided into which two categories?


“plumbing “ and “Porcelain”

Where can you typically find the README file for a project on GitHub ? at the bottom of the main repository. 

a github repository contains .  files related to your project , history and collaboration tools


The Github issues feature is used to track, bugs and features. 

drupal programmatically get maintenance message from database

If you're in the page /sites/all/themes/custom/sky/templates/system/maintenance-page.tpl.php All you need to do is print the $content





print $content ;

?>

Friday 26 February 2016

How to Add Maxmind IP redirecting to your Drupal 7 theme

This is using GeoIP2 Precision - information on this can be found at http://dev.maxmind.com/geoip/geoip2/web-services Just a quick note on what you’ll need. 1. Some Credits in your Maxmind account http://www.maxmind.com/en/geoip2-precision-services 2. Your domain needs to be on the Javascript Domains list. In your Drupal Template either in template.php or in page.preprocess.php

we need to add the maxmind js .

drupal_add_js('http://js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js', 'external');

In my code I’ve wrapper this in a check to see what page we’re on as I only need it on the front page.

In the themes .info file we have added the line to include this script

scripts[] = js/custom/rcni.maxmind.js

Here’s my code for that file. This is just a either UK or Rest of the World split.
If the page is the same that we are on then we’ll go no where.
And I’ve also made it so to activate this check we’ll add the class ‘ipswitch’ to the page we want it on.


(function ($) {
Drupal.behaviors.rcniMaxmind = {
attach: function (context, settings) {

// this code only needs to run once on landing.

if ( $( "body" ).hasClass( "ipswitch" ) ) {
var redirect = (function () {
/* This implements the actual redirection. */
var redirectBrowser = function (site) {
var uri = 'http://' + window.location.host + '/' + site;
window.location = uri;
};

/* These are the country codes for the countries we have sites for.
* We will check to see if a visitor is coming from one of these countries.
* If they are, we redirect them to the country-specific site. If not, we
* redirect them to world.example.com */
var sites = {
"gb": true
};
var defaultSite = "row";
var onSuccess = function (geoipResponse) {

var site;
/* There's no guarantee that a successful response object
* has any particular property, so we need to code defensively. */
if (!geoipResponse.country.iso_code) {
redirectBrowser("gb");
return;
}
/* ISO country codes are in upper case. */
var code = geoipResponse.country.iso_code.toLowerCase();

if (sites[code]) {
if (code == 'gb') {
site = "uk/home"
var currentLoc = window.location.pathname;
var pathCheck = '/' + site;

if ( window.location.pathname === pathCheck) {
console.log('do nothing');
return;
}
else {
redirectBrowser(site);
}

}
}
else {
site = "row/home"
redirectBrowser(site);
}
};

/* We don't really care what the error is, we'll send them
* to the default site. */
var onError = function (error) {
redirectBrowser("uk/home");
};

return function () {
geoip2.country(onSuccess, onError);
};
}());

redirect();
}
}
};
})(jQuery);

Thursday 25 February 2016

Setting up Vlad development environment

The place to go for more information is https://www.vagrantup.com  & https://vlad-docs.readthedocs.org

What is It ?  A tool for building complete development environments.

Why ?   To decrease development setup time and increase production parity.


What do we need to set up on our local machines -
 
  1. Virtual Box
  2. Vagrant
  3. Ansible - use PIP 

The first two are as easy as going to these websites and downloading the latest versions https://www.virtualbox.org/  and https://www.vagrantup.com/downloads.html

Downloading the third App 'Ansible' may depend on your operating system . At the time of writing it was recommended by Dan that we should install version 1.9.4 using 'pip' .  Or though homebrew will work also. The following command should work

sudo pip install ansible==1.9.4 

This didn't work for me an I ended up install the lastest version with Homebrew, but everything seems to be working fine.

 
Here endeth the set up for your local environment that will only need to be done once.  From here on the instructions will need to be followed per project 

Per Project Settings 
__________________
Once set up we can up a project with inside our folder we should then have a 'docroot' folder .  

In terminal 'cd' into your project folder 
INSTALL VLAD -  which is grabbed from the github page https://github.com/hashbangcode/vlad  - at the time of writing we should be taking Vlad from DEV and not master. 
HOWEVER at the time of writing it's been requested we download the dev version as there are important changes and features on there that we'll need. 
We need to set up a settings.yml file which will go in a sibling folder to docroot called 'settings' 


So here you'll need to create the folder 'settings' and then you can copy an example file from vlad_guts/example.vlad_settings.yml .

Here's my file from my test set up
-


---
# Webserver settings webserver_hostname: 'test.local' webserver_hostname_aliases:  - 'www.test.local'
# Vagrantfile configuration boxipaddress: "192.168.111.122" boxname: "test" host_synced_folder: "../docroot" aux_synced_folder: "../vlad_aux"

 #SSH Settings use_host_id: true

  #CPUs and memory to be allocated vm_cpus: "auto" vm_memory: "auto"
 php_version: "5.6"
 aberdeen_cli_install: true

 db_import_up: true


  • Paths in settings are relevant to wherever the Vagrant file is.  
  • Aux folder should be set to "../vlad_aux" so it appears as a sibling, as in the image above. 
  • Box Ip Address to be unique for each dev and project.  This will need to be agreed with other Devs
  • Aberdeen Cli installation has been added to sql sync database straight from Aberdeen

  •  DB import up - will make sure a Database will import if in vlad_aux/db_io/[path_to_file] if it exists.  More information here .  https://vlad-docs.readthedocs.org/en/latest/usage/variables/
cd into the folder where the 'Vagrantfile' is . 
'cd vlad'
'vagrant up'
To see the database with adminer then add this before your domain  http://www.adminer.domain

Sharing a project .  

we can use the command 'vagrant share'  to get a url to share our project with others , but first we'll need to set ourselves up on https://atlas.hashicorp.com/

Tuesday 23 February 2016

Drupal 7 views : How to sort order on a Multiple data field.

The task - What we have is a column of Dates of when the entity was sent. This could be one or more dates, ie multivalued . The objective here is for each row to present the most recent sent date and for the rows to be sorted by the date. 
 I encountered 2 issues that I had to get over.  
If we we’re just to add a sort here then we get multiple returns for each Entity, which we don’t want. 
The second issue is that the date ‘Multiple Field Settings’ - ‘Reversed’ tick box doesn’t effect my result ordering in that field.  And therefore display the oldest date and not most recent. 
Let’s take a look at the first issue.  To resolve this what I like to do is group the fields together and present 1 row for each Entity , but by doing so the normal way through > Table > Settings > ‘Grouping field’  .  Here I get the right results in the right order but it creates multiple tables for each row.  The solution is to use the module ['https://www.drupal.org/project/views_table_rowspan'] Views Table Rowspan.  With this module you
  1. Install it
  2. Clone your View ‘display’ and this time set the ‘Format’ to ‘table rowspan’ 
  3. now in Table Rowspan > Settings .  Add all the fields and then tick ‘Merge rows in table’ 



Now with that second issue a full fix is to investigate and write a patch. Like https://www.drupal.org/node/2070313  

I’ll be taking a look at this shortly . In the meantime though it can be dealt with in the template layer ( as long as it’s not being outputted to CSV ) .  For my template fix I output all results with out any styling or HTML. Separated with ‘,’ - if the string passes has a comma then I split the value in to an array and take the last element as my date. 
Here's code I used in the template overwrite.


$html_wrapper = '%REPLACE%'; 



if (strpos($output, ',') != TRUE ){

  print str_replace('%REPLACE%', $output, $html_wrapper);

}

elseif(strpos($output, ',') == TRUE ) {

  $date_array = explode(',', $output);

  $last_date = end($date_array);

  print str_replace('%REPLACE%', $last_date, $html_wrapper) ;

}

else {

  print str_replace('%REPLACE%', $output, $html_wrapper);

}

Monday 22 February 2016

Drupal 7 Jquery statement to add Class and remove when tabbing into an input

Here's a snippet of code that will allow you to change the class of an input field in your form when you tab into it.

I've got this in a file in my theme /sites/all/themes/mytheme/js/custom

Remember to add this file to the file /sites/all/themes/mytheme/mytheme.info

(function ($) {
Drupal.behaviors.skyFocus = {
attach: function (context, settings) {

var focusClass = "has-focus";

$('.form-text').keyup(function(e) {
if(e.keyCode === 9){
$(this).addClass(focusClass);
}
}
);
$('.form-text').focusout(function() {
$(this).removeClass(focusClass);
}
);

}
};
})(jQuery);

Friday 19 February 2016

Drupal 7 Views - Views Filter Field Default value 'all' change.

The change is to the field handlers .

To do this we can extend the field handler class for this module which we have in /sites/all/modules/contrib/views_filterfield/handlers/views_filterfield.inc - which itself extends the ‘views_handler_field'

You’ll need to put this new class in a custom module of your own . We’ve got all ours in Custom module called reports and the folders are arranged like this.

Reports /
admin_views_defualt /
includes/
src/
Controller /
Plugin /
Reports/
SqlQueries/
Views/
Wrappers/
theme/

At this point it you haven’t worked with classes before I’d need to go into more depth into namespacing and organisation but don’t want to get too sidetracked. So you’ll have to find this out yourself it you’re not sure.

In the class extension of ‘views_filterfield’ make the change to render the default dates correctly as they’ve been rendered into a sub-array.

We do a check to see if our filter is indeed empty. And we then go and get the value we want to fill it with and put that in the output. Unfortunately it’s not quite that straight forward as we also need to create a load of create_function calls to fill the array where needed.

Here’s the code



/**

 * @file

 * Contains Drupal\report\Views\Filter\DateFilterFieldFilter.

 *

 * The only purpose for extending these filters is to handle dates correctly;

 * by default they don't work because they've been rendered into a sub-array.

 */



namespace Drupal\report\Views\Filter;



use views_filterfield;



class DateFilterFieldFilter extends views_filterfield {



  function render($values) {

    $output = ['all'];



    $filter = $this->get_filter($this->options['views_filterfield_field']);



    // BEGIN CHANGES

    if (!empty($this->view->exposed_input[$filter['expose']['identifier']]['value'])) {

      if (is_array($this->view->exposed_input[$filter['expose']['identifier']]['value'])) {

        $output = $this->view->exposed_input[$filter['expose']['identifier']]['value'];

      }

      else {

        // Turn a single value into an array, so the transform array_walk

        // function works.

        $output = [$this->view->exposed_input[$filter['expose']['identifier']]['value']];

      }

    }

    // END CHANGES



    // Lots of create_function() calls next, as array_walk does not generally

    // play nice with internal functions, as it passes too many args. These

    // will simply throw a warning and not work.

    // @see http://php.net/manual/en/function.array-walk.php




    // Transform spaces to dashes.

    if (!empty($options['views_filterfield_transform_dash'])) {

      array_walk($output, create_function('&$val', '$val = strtr($val, array(" " => "-"));'));

    }



    // Transform case as needed by walking the array of values.

    switch ($this->options['views_filterfield_case']) {

      case 1: // Lower case.

        array_walk($output, create_function('&$val', '$val = drupal_strtolower($val);'));

        break;



      case 2: // Title case.

        array_walk($output, create_function('&$val', '$val = ucwords($val);'));

        break;



      case 3: // Upper case.

        array_walk($output, create_function('&$val', '$val = drupal_strtoupper($val);'));

        break;



      case 4: // Sentence case.

        array_walk($output, create_function('&$val', '$val = drupal_ucfirst($val);'));

        break;

    }



    // Turn the transformed array values into a delimited string.

    $separator = $this->options['views_filterfield_separator'];

    $output = implode($separator, $output);



    // Do some basic sanity checking. We don't want crazy values, do we?

    $checked = filter_xss($output);

    return $checked;

  }



}


Thursday 11 February 2016

Creating exact sized files to help with testing - using terminal and OS X

Syntax for mkfile is as follows:



mkfile -n size[b|k|m|g] filename



Thanks to Os X Daily for the Creating a Large file tip.  It's not only useful for large files tho !

Monday 8 February 2016

PHP comparing if 2 files were modified in X amount of time of each other

So I have 2 files and want to know that they were created at the same time, although there may be a small gap between them, let's say not over 2 mins.

filemtime(filename) - will give us a Unix time stamp.  So

$file_1_timestamp = filemtime($path_to_file1);
$file_2_timestamp = filemtime($path_to_file2);

If ( $file_1_timestamp > $file_2_timestamp-120 && $file_1_timestamp < $file_2_timestamp+120 ) {

TRUE

}

Friday 5 February 2016

Mysql using SUM and DISTINCT - Why not use GROUP


Mysql using SUM and DISTINCT  - Why not use GROUP

Yes the answers in the title .  Consider

SELECT SUM(DISTINCT te.field_company_total_employees_value)

    FROM field_data_field_company_total_employees AS te

    INNER JOIN  field_data_field_user_company AS uc ON te.entity_id = uc.field_user_company_target_id

    INNER JOIN field_claiming_user AS cu ON uc.entity_id = cu.field_claiming_user_target_id

    INNER JOIN field_data_field_urn_offer as uo ON cu.entity_id = uo.entity_id

    WHERE uo.field_urn_offer_target_id = 20

GROUP BY te.id


Produced the results wanted. 

Wednesday 3 February 2016

How to access your .ssh folder from Mac OS File chooser


Recently while in Filezilla and needing to open my id_rsa.pub file in the hidden folder .ssh ; I couldn’t see the folder. 


To view folder ( as long as you know the folder name ) you can use. CMD + SHIFT + G 

Wednesday 27 January 2016

Fix User warning: division by zero in ctools_math_expr->trigger() (line 360 of /*/ctools/includes/math-expr.inc) error

This was on Drupal 7 Views using the Global Math Expression field.

If you set your field up like this


No Results text - 1[number your dividing][number your dividing].1

Count the number 0 as empty

and last of all Hide rewriting.  Otherwise the 1 will be written in the table.


Always comes in under 0% .  Which is what I wanted to show.


If the re-written value is an issue you could possible duplicate the field ;)