You are here

Miscelaneous

Drupal: show/hide location fields with module Conditional Fields

Not so frequently asked questions and stuff: 

Image

Situation

You're using module Conditional Fields to show/hide a few fields depending on another field value. You notice that everything works except your location fields, which don't respond to any trigger.

Example: Let's say you have the following profile2:

Field Type Widget Misc
field_champ1 List(text) Select list Values: "Valeur 1", "Valeur 2" or "Valeur 3"
field_champ2 Location Location field
field_champ3 Text Text

You set up the following conditional interactions:

  • field_champ2 is only visible when field_champ1 has value "Valeur 2"
  • field_champ3 is only visible when field_champ1 has value "Valeur 1"

Then, you open an edit form of this profile, and notice that only the second interaction works.

Finding what cause the problem

Let's dig into the code.

In modules/conditional_fields/conditional_fields.module, function conditional_fields_element_after_build(...) seems to be the one that attach the dependencies from the form.

  if (isset($dependencies['dependents'][$field['#field_name']])) {
    foreach ($dependencies['dependents'][$field['#field_name']] as $id => $dependency) {
      if (!isset($form['#conditional_fields'][$field['#field_name']]['dependees'][$id])) {
        conditional_fields_attach_dependency($form, array('#field_name' => $dependency['dependee']), $field, $dependency['options'], $id);
      }
    }
  }

  // Attach dependee.
  // TODO: collect information about every element of the dependee widget, not
  // just the first encountered. This bottom-up approach would allow us to
  // define per-element sets of dependency values.
  if (isset($dependencies['dependees'][$field['#field_name']])) {
    foreach ($dependencies['dependees'][$field['#field_name']] as $id => $dependency) {
      if (!isset($form['#conditional_fields'][$field['#field_name']]['dependents'][$id])) {
        conditional_fields_attach_dependency($form, $field, array('#field_name' => $dependency['dependent']), $dependency['options'], $id);
      }
    }
  }

Debugging shows that our location field does not validate the preceding condition:

  // Some fields do not have entity type and bundle properties. In this case we
  // try to use the properties from the form. This is not an optimal solution,
  // since in case of fields in entities within entities they might not correspond,
  // and their dependencies will not be loaded.
  if (isset($field['#entity_type'], $field['#bundle'])) {
    $entity_type = $field['#entity_type'];
    $bundle = $field['#bundle'];
  }
  elseif (isset($form['#entity_type'], $form['#bundle'])) {
    $entity_type = $form['#entity_type'];
    $bundle = $form['#bundle'];
  }
  else {
    return $element;
  }

This means that our field was not build with a reference to its profile2 entity.

These field form entries are built by field_multiple_value_form(...) in modules/field/field.form.inc:

      $element = array(
        '#entity_type' => $instance['entity_type'],
        '#entity' => $form['#entity'],
        '#bundle' => $instance['bundle'],
        '#field_name' => $field_name,
        '#language' => $langcode,
        '#field_parents' => $parents,
        '#columns' => array_keys($field['columns']),
        // For multiple fields, title and description are handled by the wrapping table.
        '#title' => $multiple ? '' : $title,
        '#description' => $multiple ? '' : $description,
        // Only the first widget should be required.
        '#required' => $delta == 0 && $instance['required'],
        '#delta' => $delta,
        '#weight' => $delta,
      );
      if ($element = $function($form, $form_state, $field, $instance, $langcode, $items, $delta, $element)) {
...

Hum, once build, it's passed into another function. Let's find it.

It's location_cck_field_widget_form(...) in modules/location/contrib/location_cck/location_cck.module:

    $element = array(
      '#type' => 'location_element',
      '#has_garbage_value' => TRUE,
      '#value' => '',
      '#title' => t($instance['label']),
      '#description' => t($instance['description']),
      '#required' => $instance['required'],
      '#location_settings' => $settings,
      '#default_value' => $location,
    );

    return $element;

Since the returned element doesn't care about what was passed to it, the entity elements are indeed missing.

Working around the problem

One solution would be to patch module location.

Another one is to alter the form and add the missing entries manually.

function my_module_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {
  if ($entity_type == 'profile2' && $entity->type == 'profile_debug') {
    $form['field_champ2']['#entity_type'] = $entity_type;
    $form['field_champ2']['#bundle'] = $entity->type;

    if (isset($form['field_champ2'][LANGUAGE_NONE])) {
      $form['field_champ2'][LANGUAGE_NONE]['#entity_type'] = $entity_type;
      $form['field_champ2'][LANGUAGE_NONE]['#bundle'] = $entity->type;
    }
  }
}

That's it: location field field_champ2 now behaves correctly.

How to create a certificate to send APNS notifications, manually using OpenSSL

Not so frequently asked questions and stuff: 

Image

Create your key.

openssl genrsa -out truc.example.org.key 2048

Create the certificate request:

openssl req -new -key truc.example.org.key -out truc.example.org.csr

Upload the CSR to Apple, and get the resultant certificate.

Optionally convert the certificate to PEM format.

openssl x509 -inform der -in truc.example.org.cer -out truc.example.org.crt.pem

Check if you can connect to APNS with your credentials:

openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert truc.example.org.crt.pem -key truc.example.org.key

Use the key and certificate files for profit.

How to add HTTP Authorization to Synology's web interface

Not so frequently asked questions and stuff: 

Image

Situation

This article is relevant to a DS412+ appliance.

You're using a small Synology server. You use the web interface for whatever purpose. (the one at http://nas.example.com:5001). You'd like to access this interface remotely, but you are afraid to open the port on your firewall since you don't trust the associated CGI scripts.

Solution

Add HTTP auth to httpd, so that any request must go through a password.

Create file /usr/syno/etc/httpd/passwd (here or in whatever location you fancy) and create your credential database.

user:$apr1$mN37yOqk$7wKJq7B710AcJSa7Y6WJD1
user2:$apr1$4zha9SDn$Vcs481LpfkUMx1Y/SybKw.
user3:$apr1$Gq/AeNY4$68DGcCVo6BdOSy1eSDjkP/
user4:$apr1$ihJ0/hfG$1MUZzj3LYKG7tU3P7S9hh/

Create file /etc/httpd/conf/extra/httpd-something.conf and configure httpd to serve on port 5002 the same content as port 5001, but with basic HTTP authentication.

Listen 5002

LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authn_file_module modules/mod_authn_file.so


    ServerName *
    ServerAlias *

    SSLEngine on

    
        AuthType Basic
        AuthName "Secure Content"
        AuthBasicProvider file
        AuthUserFile /usr/syno/etc/httpd/passwd
        Require valid-user
    

Edit /etc/httpd/conf/httpd.conf-sys and include the preceding file at the end.

Include conf/extra/httpd-something.conf

Restart httpd.

/usr/syno/etc/rc.d/S97apache-sys.sh restart

Forward port 5002 in your firewall.

Image

Enjoy your (a tiny bit more) secured NAS from anywhere in the world.

How to get the serial number of a SunFire V20Z Server

Not so frequently asked questions and stuff: 

If you need to get the serial number of an old SunFire v20Z server, use ipmi:

yourhost# ipmitool fru
FRU Device Description : Builtin FRU Device (ID 0)
Error receiving message: Input/output error
 Chassis Type                    : Rack Mount Chassis
 Chassis Part Number     : 602-2844-01
 Chassis Serial                  : XG123456789
 Board Mfg Date        : Mon Jan 24 00:00:00 2005
 Board Mfg             : S-SCI448
 Board Product         : NWSBIDff
 Board Serial          : M123M45E
 Board Part Number     : S02035
 Product Manufacturer  : Sun Microsystems
 Product Name          : Sun Fire(tm) V20z
 Product Part Number   : 602-2844-01
 Product Version       : A02
 Product Serial        : XG123456

FRU Device Description : cpu0.mem0.vpd (ID 1)
 Board Mfg Date        : Sat Jan 15 00:00:00 2005
 Board Mfg             : ce00000000000000
 Board Product         : 1GB DDR333 (PC2700) ECC
 Board Serial          : 02013815
 Board Part Number     : M3 12L2820EG0-CB3
 Product Manufacturer  : ce00000000000000
 Product Name          : 1GB DDR333 (PC2700) ECC
 Product Part Number   : M3 12L2820EG0-CB3
 Product Version       : 3045
 Product Serial        : 02123456

FRU Device Description : cpu0.mem1.vpd (ID 2)
 Board Mfg Date        : Sat Jan 15 00:00:00 2005
 Board Mfg             : ce00000000000000
 Board Product         : 1GB DDR333 (PC2700) ECC
 Board Serial          : 02053817
 Board Part Number     : M3 12L2820EG0-CB3
 Product Manufacturer  : ce00000000000000
 Product Name          : 1GB DDR333 (PC2700) ECC
 Product Part Number   : M3 12L2820EG0-CB3
 Product Version       : 3045
 Product Serial        : 02123456

[...]

This works at least on FreeBSD.

How to configure the SPA500S Attendant Console with Asterisk/FreePBX

Not so frequently asked questions and stuff: 

What we have:

  • A Cisco SPA525G IP Phone with a SPA500S Attendant Console
  • A FreePBX Server
  • Some other SIP phones

We want to configure FreePBX and the attendant Console.

FreePBX

Make sure that picking up calls work.

See http://www.freepbx.org/support/documentation/howtos/how-to-use-callgroups-and-pickgroups to set up pickgroups.

Apart from that, FreePBX should configure the hints correctly without any additional configuration.

The phone


Make sure that the phones are allowed to dial feature codes like **1234. On the SPA525G, you must modify the dialplan in the phone's configuration (set it to something like (*xx.|**xx.|xx.)).

The Attendant Console


Attendant Console Call Pickup Code: **# (feature code for Directed Call Pickup + #, # will be replaced by the extension number). If you set it to *8 (feature code for Asterisk General Call Pickup), the console will pick _any_ ringing phone, so if two of them are ringing at the same time, you don't know which one will get chosen.

Unit keys: fnc=sd+cp+blf;sub=extension@server;nme=extension
Exemple: fnc=sd+cp+blf;sub=1742@192.168.3.156;nme=1742

Sources

How to format a file size in Excel (B, KB, MB, GB)

Not so frequently asked questions and stuff: 

In French:

=SI(A1>=1024*1024*1024; TEXTE(A1/(1024*1024*1024); "0")&" GiB";
SI(A1>=1024*1024; TEXTE((A1/(1024*1024)); "0")&" MiB"; 
SI(A1>=1024; TEXTE((A1/(1024)); "0")&" KiB";
TEXTE(A1; "0")&" B")))

In English:

=IF(A1>=1024*1024*1024; TEXT(A1/(1024*1024*1024); "0")&" GiB";
IF(A1>=1024*1024; TEXT((A1/(1024*1024)); "0")&" MiB"; 
IF(A1>=1024; TEXT((A1/(1024)); "0")&" KiB";
TEXT(A1; "0")&" B")))

How to display output in more than one window with VLC Media Player.

Not so frequently asked questions and stuff: 

Cloning

To display output in more than one window, video cloning can be used. To use this, specify

--vout-filter=clone

on the command line: this tells vlc to use cloning. You also need to tell vlc what output modules you want with, for example,

--clone-vout-filter=caca,glx
--clone-count=2

Source: http://wiki.videolan.org/Video_Output

How to compress TI89 text files from 89t to 89y

Not so frequently asked questions and stuff: 
Subscribe to Miscelaneous