You are here

organigrams.module in Organigrams 7

Same filename and directory in other branches
  1. 8.2 organigrams.module
  2. 8 organigrams.module

Defines the organigrams functions and entity types.

File

organigrams.module
View source
<?php

/**
 * @file
 * Defines the organigrams functions and entity types.
 */

/**
 * Implements hook_entity_info().
 */
function organigrams_entity_info() {
  $entities = array();

  // Declare the 'organigrams_item' entity.
  $entities['organigrams_item'] = array(
    'label' => t('Organigram item'),
    'controller class' => 'OrganigramsItemController',
    'base table' => 'organigrams_item_data',
    'fieldable' => FALSE,
    'entity keys' => array(
      'id' => 'iid',
      'bundle' => 'organigrams_machine_name',
      'label' => 'name',
    ),
    'bundle keys' => array(
      'bundle' => 'machine_name',
    ),
    'bundles' => array(),
    'module' => 'organigrams',
  );

  // Add all organigrams names as bundle to the organigrams item.
  foreach (organigrams_get_names() as $machine_name => $organigrams) {
    $entities['organigrams_item']['bundles'][$machine_name] = array(
      'label' => $organigrams->name,
      'admin' => array(
        'path' => 'admin/structure/organigrams/%organigrams_machine_name',
        'real path' => "admin/structure/organigrams/{$machine_name}",
        'bundle argument' => 3,
        'access callback' => 'organigrams_user_access',
        'access arguments' => array(
          'edit',
          3,
        ),
      ),
    );
  }

  // Declare the 'organigrams' entity.
  $entities['organigrams'] = array(
    'label' => t('Organigram'),
    'controller class' => 'OrganigramsController',
    'base table' => 'organigrams_data',
    'entity keys' => array(
      'id' => 'oid',
      'label' => 'name',
    ),
    'fieldable' => TRUE,
    'bundles' => array(
      'organigrams' => array(
        'label' => t('Organigram'),
        'admin' => array(
          'path' => 'admin/structure/organigrams',
        ),
      ),
    ),
    'view modes' => array(
      'organigram' => array(
        'label' => t('Organigram'),
        'custom settings' => TRUE,
      ),
      'organigram_block' => array(
        'label' => t('Organigram block'),
        'custom settings' => TRUE,
      ),
    ),
    'access callback' => 'organigrams_entity_access',
    'module' => 'organigrams',
  );
  return $entities;
}

/**
 * Implements hook_entity_property_info().
 */
function organigrams_entity_property_info() {
  $info = array();

  // Add meta-data about the basic organigrams item properties.
  $properties =& $info['organigrams_item']['properties'];

  // Organigrams item related properties.
  $properties['iid'] = array(
    'label' => t('Organigram item ID'),
    'description' => t('The unique ID of the organigram item.'),
    'type' => 'integer',
    'schema field' => 'iid',
  );
  $properties['name'] = array(
    'label' => t('Name'),
    'description' => t('The name of the organigram item.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => TRUE,
    'schema field' => 'name',
  );
  $properties['parent'] = array(
    'label' => t('Parent item'),
    'description' => t('The parent terms of the taxonomy term.'),
    'setter callback' => 'organigrams_metadata_organigrams_item_setter',
    'type' => 'organigrams_item',
    'schema field' => 'parent',
  );
  $properties['position'] = array(
    'label' => t('Position'),
    'description' => t('The position of the organigram item.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => TRUE,
    'schema field' => 'position',
  );
  $properties['url'] = array(
    'label' => t('URL'),
    'description' => t('Add a link to this URL to the organigram item.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'url',
  );
  $properties['border_color'] = array(
    'label' => t('Border color'),
    'description' => t('The border color of the organigram item.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'border_color',
  );
  $properties['border_color_hover'] = array(
    'label' => t('Border color hover'),
    'description' => t('The border color of the organigram item when hovering over it if it has a URL.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'border_color_hover',
  );
  $properties['background_color'] = array(
    'label' => t('Background color'),
    'description' => t('The background color of the organigram item.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'background_color',
  );
  $properties['background_color_hover'] = array(
    'label' => t('Background color hover'),
    'description' => t('The background color of the organigram item when hovering over it if it has a URL.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'background_color_hover',
  );
  $properties['font_color'] = array(
    'label' => t('Font color'),
    'description' => t('The font color of the organigram item.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'font_color',
  );
  $properties['font_color_hover'] = array(
    'label' => t('Font color hover'),
    'description' => t('The font color of the organigram item when hovering over it if it has a URL.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'font_color_hover',
  );
  $properties['bold_border'] = array(
    'label' => t('Bold border'),
    'description' => t('Emphasize the organigram item with an extra border.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'bold_border',
  );
  $properties['image_url'] = array(
    'label' => t('Image URL'),
    'description' => t('The image URL of an image to add to the organigram item.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'image_url',
  );
  $properties['image_alignment'] = array(
    'label' => t('Image alignment'),
    'description' => t('The alignment of the image in the organigram item.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'image_alignment',
  );
  $properties['weight'] = array(
    'label' => t('Weight'),
    'description' => t('The weight of the organigram item, which is used for ordering items during display.'),
    'setter callback' => 'entity_property_verbatim_set',
    'schema field' => 'weight',
  );
  $properties['organigram'] = array(
    'label' => t('organigram'),
    'description' => t('The organigram the organigram item belongs to.'),
    'setter callback' => 'organigrams_metadata_organigrams_item_setter',
    'type' => 'organigrams',
    'required' => TRUE,
    'schema field' => 'oid',
  );

  // Add meta-data about the basic organigrams properties.
  $properties =& $info['organigrams']['properties'];

  // Organigrams related variables.
  $properties['oid'] = array(
    'label' => t('Organigram ID'),
    'description' => t('The unique ID of the organigram.'),
    'type' => 'integer',
    'schema field' => 'oid',
  );
  $properties['name'] = array(
    'label' => t('Name'),
    'description' => t('The name of the organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => TRUE,
    'schema field' => 'name',
  );
  $properties['machine_name'] = array(
    'label' => t('Machine name'),
    'description' => t('The machine name of the organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'type' => 'token',
    'required' => TRUE,
    'schema field' => 'machine_name',
  );
  $properties['description'] = array(
    'label' => t('Description'),
    'description' => t('The optional description of the organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'sanitize' => 'filter_xss',
    'schema field' => 'description',
  );
  $properties['status'] = array(
    'label' => t('status'),
    'description' => t('The published status of the organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'status',
  );
  $properties['canvas_width'] = array(
    'label' => t('Canvas width'),
    'description' => t('Specify the width in pixels of the organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'canvas_width',
  );
  $properties['canvas_height'] = array(
    'label' => t('Canvas height'),
    'description' => t('Specify the height in pixels of the organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'canvas_height',
  );
  $properties['center'] = array(
    'label' => t('Center'),
    'description' => t('Boolean indicating whether the organigram should align on the center of the page.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'center',
  );
  $properties['fit'] = array(
    'label' => t('Fit in given width'),
    'description' => t('Boolean indicating whether the organigram should rescale to the given width.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'fit',
  );
  $properties['node_width'] = array(
    'label' => t('Node width'),
    'description' => t('Specify the width in pixels of the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'node_width',
  );
  $properties['node_height'] = array(
    'label' => t('Node height'),
    'description' => t('Specify the height in pixels of the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'node_height',
  );
  $properties['top_radius'] = array(
    'label' => t('Top radius'),
    'description' => t('Specify the radius of the top corners in pixels of the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'top_radius',
  );
  $properties['bottom_radius'] = array(
    'label' => t('Bottom radius'),
    'description' => t('Specify the radius of the bottom corners in pixels of the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'bottom_radius',
  );
  $properties['shadow_offset'] = array(
    'label' => t('Shadow offset'),
    'description' => t('Specify the shadow offset in pixels of the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'shadow_offset',
  );
  $properties['horizontal_space'] = array(
    'label' => t('Horizontal space'),
    'description' => t('Specify the horizontal space in pixels between the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'horizontal_space',
  );
  $properties['vertical_space'] = array(
    'label' => t('Vertical space'),
    'description' => t('Specify the vertical space in pixels between the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'vertical_space',
  );
  $properties['horizontal_offset'] = array(
    'label' => t('Horizontal offset'),
    'description' => t('Specify the horizontal offset in pixels between the l and r items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'horizontal_offset',
  );
  $properties['line_color'] = array(
    'label' => t('Line color'),
    'description' => t('Specify the connection lines color in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'line_color',
  );
  $properties['border_color'] = array(
    'label' => t('Border color'),
    'description' => t('Specify the border color of the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'border_color',
  );
  $properties['border_color_hover'] = array(
    'label' => t('Border color hover'),
    'description' => t('Specify the border color of the items with URL in this organigram when hovering over them.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'border_color_hover',
  );
  $properties['background_color'] = array(
    'label' => t('Background color'),
    'description' => t('Specify the background color of the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'background_color',
  );
  $properties['background_color_hover'] = array(
    'label' => t('Background color hover'),
    'description' => t('Specify the background color of the items with URL in this organigram when hovering over them.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'background_color_hover',
  );
  $properties['font_color'] = array(
    'label' => t('Font color'),
    'description' => t('Specify the font color of the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'font_color',
  );
  $properties['font_color_hover'] = array(
    'label' => t('Font color hover'),
    'description' => t('Specify the font color of the items with in this organigram when hovering over them.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'font_color_hover',
  );
  $properties['font_name'] = array(
    'label' => t('Font name'),
    'description' => t('Specify the font name of the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'font_name',
  );
  $properties['font_size'] = array(
    'label' => t('Font size'),
    'description' => t('Specify the font size in pixels of the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'font_size',
  );
  $properties['line_height'] = array(
    'label' => t('Line height'),
    'description' => t('Specify the line height in pixels for the text in the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'line_height',
  );
  $properties['vertical_alignment'] = array(
    'label' => t('Vertical text alignment'),
    'description' => t('Specify the vertical text alignment of the items in this organigram.'),
    'setter callback' => 'entity_property_verbatim_set',
    'required' => FALSE,
    'schema field' => 'vertical_alignment',
  );
  return $info;
}

/**
 * Implements hook_entity_view().
 */
function organigrams_entity_view($entity, $type, $view_mode, $langcode) {

  // Load all pseudofields.
  $extrafields = field_extra_fields_get_display('organigrams', $type, $view_mode);

  // Add the name if visible.
  if (isset($extrafields['name']) && !empty($extrafields['name']['visible'])) {
    $entity->content['name'] = array(
      '#markup' => check_plain($entity->name),
      '#weight' => $extrafields['name']['weight'],
    );
  }

  // Add the description if visible.
  if (isset($extrafields['description']) && !empty($extrafields['description']['visible'])) {
    $entity->content['description'] = array(
      '#markup' => nl2br(check_plain($entity->description)),
      '#weight' => $extrafields['description']['weight'],
    );
  }

  // Add the actual rendered organigram if visible.
  if (isset($extrafields['organigram']) && !empty($extrafields['organigram']['visible'])) {

    // Generate a unique ID for the current embed request.
    // A unique ID is needed to prevent collisions between multiple organigrams
    // on one page.
    $entity->unique_id = drupal_hash_base64(uniqid(mt_rand(), TRUE) . mt_rand());

    // Compose the organigram.
    $organigram = organigrams_compose_organigrams($entity, $langcode);

    // Add it to the content.
    $entity->content['organigram'] = array(
      '#markup' => render($organigram),
      '#weight' => $extrafields['organigram']['weight'],
    );
  }
}

/**
 * Implements hook_field_extra_fields().
 */
function organigrams_field_extra_fields() {
  $return = array();
  $info = entity_get_info('organigrams');
  foreach (array_keys($info['bundles']) as $bundle) {
    $return['organigrams'] = array(
      $bundle => array(
        // Add the entity fields to the fields UI so the user can change the
        // order.
        'form' => array(
          'name' => array(
            'label' => t('Name'),
            'description' => t('Text'),
            'weight' => -6,
          ),
          'description' => array(
            'label' => t('Description'),
            'description' => t('Long text'),
            'weight' => -5,
          ),
          'status' => array(
            'label' => t('Published'),
            'description' => t('Checkbox'),
            'weight' => -4,
          ),
          'organigram_settings' => array(
            'label' => t('Organigram settings'),
            'description' => t('Fieldgroup'),
            'weight' => -3,
          ),
          'item_settings' => array(
            'label' => t('Organigram item settings'),
            'description' => t('Fieldgroup'),
            'weight' => -2,
          ),
          'font_settings' => array(
            'label' => t('Organigram font settings'),
            'description' => t('Fieldgroup'),
            'weight' => -1,
          ),
        ),
        // Add the entity fields which eventually will be displayed to the view
        // modes so the user can change the order and optionally hide them.
        'display' => array(
          'name' => array(
            'label' => t('Name'),
            'weight' => -5,
          ),
          'description' => array(
            'label' => t('Description'),
            'weight' => -4,
          ),
          'organigram' => array(
            'label' => t('Organigram'),
            'weight' => -3,
          ),
        ),
      ),
    );
  }
  return $return;
}

/**
 * Implements hook_block_info().
 */
function organigrams_block_info() {

  // Initialize blocks array.
  $blocks = array();

  // Iterate through all the available organigrams.
  foreach (organigrams_get_names() as $organigram) {

    // Add organigram block.
    $blocks[$organigram->oid] = array(
      'info' => t('Organigram: !organigram', array(
        '!organigram' => $organigram->name,
      )),
    );
  }

  // Return available blocks.
  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function organigrams_block_view($delta = '') {

  // Initialize block variable.
  $block = array(
    'subject' => NULL,
    'content' => NULL,
  );

  // Load the organigram.
  $organigram = organigrams_load((int) $delta);
  if (!empty($organigram) && organigrams_entity_access('view', $organigram)) {

    // Generate the organigram renderable array.
    $organigram_renderable_array = entity_view('organigrams', array(
      $organigram,
    ), 'organigram_block');

    // Check if generating the organigram was successful.
    if (is_array($organigram_renderable_array)) {

      // Render the organigram renderable array and save the content in the
      // block.
      $block['content'] = drupal_render($organigram_renderable_array);
    }
  }

  // Return the rendered organigram block.
  return $block;
}

/**
 * Admin menu callback to redirect to the organigram view page.
 *
 * @param mixed $organigram
 *   An organigram entity or machine name.
 */
function organigrams_redirect_to_view_page($organigram) {

  // Show not found page if no argument is given.
  if (empty($organigram)) {
    drupal_not_found();
  }

  // Define the var.
  $machine_name = '';

  // Get the machine name.
  if (is_string($organigram)) {
    $machine_name = $organigram;
  }
  elseif (isset($organigram->machine_name)) {
    $machine_name = $organigram->machine_name;
  }
  else {

    // If no machine name is found, show not found page.
    drupal_not_found();
  }

  // Redirect to the organigram view page.
  drupal_goto('organigram/' . $machine_name);
}

/**
 * Menu callback to display an organigram.
 *
 * @param mixed $organigram
 *   An organigram entity, ID or machine name.
 *
 * @return array
 *   A renderable array or drupal not found.
 */
function organigrams_view_page($organigram) {

  // Show the not found page if no argument is given.
  if (empty($organigram)) {
    drupal_not_found();
  }

  // Retrieve the organigram by ID or by machine name.
  if (!is_numeric($organigram) && is_string($organigram)) {

    // Load the organigram by machine name.
    $organigram = organigrams_machine_name_load($organigram);
  }
  elseif (is_numeric($organigram)) {
    $organigram = organigrams_load($organigram);
  }

  // Show the not found page if no organigram is loaded.
  if (empty($organigram)) {
    drupal_not_found();
  }

  // Do an access check.
  if (!organigrams_entity_access('view', $organigram)) {
    drupal_access_denied();
  }

  // Generate the organigram renderable array.
  $content = entity_view('organigrams', array(
    $organigram,
  ), 'organigram');
  return $content;
}

/**
 * Implements hook_rdf_mapping().
 */
function organigrams_rdf_mapping() {
  return array(
    array(
      'type' => 'organigrams_item',
      'bundle' => RDF_DEFAULT_BUNDLE,
      'mapping' => array(
        'rdftype' => array(
          'skos:Concept',
        ),
        'name' => array(
          'predicates' => array(
            'rdfs:label',
            'skos:prefLabel',
          ),
        ),
        'oid' => array(
          'predicates' => array(
            'skos:inScheme',
          ),
          'type' => 'rel',
        ),
        'parent' => array(
          'predicates' => array(
            'skos:broader',
          ),
          'type' => 'rel',
        ),
      ),
    ),
    array(
      'type' => 'organigrams',
      'bundle' => RDF_DEFAULT_BUNDLE,
      'mapping' => array(
        'rdftype' => array(
          'skos:ConceptScheme',
        ),
        'name' => array(
          'predicates' => array(
            'dc:title',
          ),
        ),
        'description' => array(
          'predicates' => array(
            'rdfs:comment',
          ),
        ),
      ),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function organigrams_menu() {
  $items = array();
  $items['admin/structure/organigrams'] = array(
    'title' => 'Organigrams',
    'description' => 'Create and manage organigrams.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'organigrams_form_overview_organigrams',
    ),
    'access arguments' => array(
      'administer organigrams',
    ),
    'file' => 'organigrams.admin.inc',
  );
  $items['admin/structure/organigrams/list'] = array(
    'title' => 'List organigrams',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
  );
  $items['admin/structure/organigrams/add'] = array(
    'title' => 'Add organigram',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'organigrams_form_organigrams',
    ),
    'access arguments' => array(
      'administer organigrams',
    ),
    'type' => MENU_LOCAL_ACTION,
    'file' => 'organigrams.admin.inc',
  );
  $items['admin/structure/organigrams/import'] = array(
    'title' => 'Import organigram',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'organigrams_form_import',
    ),
    'access arguments' => array(
      'administer organigrams',
    ),
    'file' => 'organigrams.admin.inc',
    'type' => MENU_LOCAL_ACTION,
  );
  $items['admin/structure/organigrams/%organigrams_machine_name'] = array(
    'title callback' => 'organigrams_title',
    'title arguments' => array(
      3,
    ),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'organigrams_form_overview_organigrams_items',
      3,
    ),
    'access callback' => 'organigrams_user_access',
    'access arguments' => array(
      'edit',
      3,
    ),
    'file' => 'organigrams_item.admin.inc',
  );
  $items['admin/structure/organigrams/%organigrams_machine_name/list'] = array(
    'title' => 'List items',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => 2,
  );
  $items['admin/structure/organigrams/%organigrams_machine_name/add'] = array(
    'title' => 'Add item',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'organigrams_form_organigrams_item',
      array(),
      3,
    ),
    'access callback' => 'organigrams_user_access',
    'access arguments' => array(
      'edit',
      3,
    ),
    'file' => 'organigrams_item.admin.inc',
    'type' => MENU_LOCAL_ACTION,
    'weight' => 1,
  );
  $items['admin/structure/organigrams/%organigrams_machine_name/import'] = array(
    'title' => 'Import items',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'organigrams_form_import_items',
      3,
    ),
    'access callback' => 'organigrams_user_access',
    'access arguments' => array(
      'edit',
      3,
    ),
    'file' => 'organigrams.admin.inc',
    'type' => MENU_LOCAL_ACTION,
    'weight' => 2,
  );
  $items['admin/structure/organigrams/%organigrams_machine_name/export'] = array(
    'title' => 'Export items',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'organigrams_form_export',
      3,
    ),
    'access callback' => 'organigrams_user_access',
    'access arguments' => array(
      'edit',
      3,
    ),
    'file' => 'organigrams.admin.inc',
    'type' => MENU_LOCAL_ACTION,
    'weight' => 3,
  );
  $items['admin/structure/organigrams/%organigrams_machine_name/view'] = array(
    'title' => 'View',
    'page callback' => 'organigrams_redirect_to_view_page',
    'page arguments' => array(
      3,
    ),
    'access callback' => 'organigrams_user_access',
    'access arguments' => array(
      'view',
      3,
    ),
    'type' => MENU_LOCAL_TASK,
    'weight' => 1,
  );
  $items['admin/structure/organigrams/%organigrams_machine_name/edit'] = array(
    'title' => 'Edit',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'organigrams_form_organigrams',
      3,
    ),
    'access callback' => 'organigrams_user_access',
    'access arguments' => array(
      'edit',
      3,
    ),
    'file' => 'organigrams.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => 5,
  );
  $items['admin/structure/organigrams/%organigrams_machine_name/delete'] = array(
    'title' => 'Delete',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'organigrams_form_confirm_delete_organigrams',
      3,
    ),
    'access callback' => 'organigrams_user_access',
    'access arguments' => array(
      'delete',
      3,
    ),
    'file' => 'organigrams.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => 6,
  );
  $items['admin/structure/organigrams/%organigrams_machine_name/item/%organigrams_item'] = array(
    'title callback' => 'organigrams_item_title',
    'title arguments' => array(
      5,
    ),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'organigrams_form_organigrams_item',
      5,
      3,
    ),
    'access callback' => 'organigrams_user_access',
    'access arguments' => array(
      'edit',
      3,
    ),
    'file' => 'organigrams_item.admin.inc',
  );
  $items['admin/structure/organigrams/%organigrams_machine_name/item/%organigrams_item/edit'] = array(
    'title' => 'Edit item',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => 0,
  );
  $items['admin/structure/organigrams/%/item/%/view_organigram'] = array(
    'title' => 'View organigram',
    'page callback' => 'organigrams_redirect_to_organigrams_view',
    'page arguments' => array(
      3,
    ),
    'access callback' => 'organigrams_user_access',
    'access arguments' => array(
      'edit',
      3,
    ),
    'file' => 'organigrams_item.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => -10,
  );
  $items['admin/structure/organigrams/%/item/%/list'] = array(
    'title' => 'List items',
    'page callback' => 'organigrams_redirect_to_organigrams_item_overview',
    'page arguments' => array(
      3,
    ),
    'access callback' => 'organigrams_user_access',
    'access arguments' => array(
      'edit',
      3,
    ),
    'file' => 'organigrams_item.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => -9,
  );
  $items['admin/structure/organigrams/%organigrams_machine_name/item/%organigrams_item/delete'] = array(
    'title' => 'Delete item',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'organigrams_form_confirm_delete_organigrams_item',
      5,
    ),
    'access callback' => 'organigrams_user_access',
    'access arguments' => array(
      'delete',
      5,
    ),
    'type' => MENU_LOCAL_TASK,
    'file' => 'organigrams_item.admin.inc',
    'weight' => 10,
  );
  $items['organigram/%organigrams_machine_name'] = array(
    'title callback' => 'organigrams_title',
    'title arguments' => array(
      1,
    ),
    'page callback' => 'organigrams_view_page',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'organigrams_user_access',
    'access arguments' => array(
      'view',
      1,
    ),
    'type' => MENU_CALLBACK,
  );
  $items['organigram/%organigrams_machine_name/view'] = array(
    'title' => 'View',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => 1,
  );
  $items['organigram/%/edit'] = array(
    'title' => 'Edit',
    'page callback' => 'organigrams_redirect_to_organigrams_item_overview',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'organigrams_user_access',
    'access arguments' => array(
      'edit',
      1,
    ),
    'file' => 'organigrams_item.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => 2,
  );
  return $items;
}

/**
 * Implements hook_permission().
 */
function organigrams_permission() {

  // Administer organigrams permission.
  $permissions = array(
    'administer organigrams' => array(
      'title' => t('Administer organigrams and items'),
    ),
  );

  // Iterate through the organigrams.
  foreach (organigrams_get_names() as $machine_name => $organigrams_info) {

    // Create the translation arguments.
    $t_args = array(
      '%organigram' => $organigrams_info->name,
    );

    // Add the edit and delete permission.
    $permissions['edit organigram ' . $machine_name] = array(
      'title' => t('Edit organigram and items in %organigram', $t_args),
    );
    $permissions['delete organigram ' . $machine_name] = array(
      'title' => t('Delete organigram items from %organigram', $t_args),
    );
  }

  // Return all permissions.
  return $permissions;
}

/**
 * Implements hook_help().
 */
function organigrams_help($path, $arg) {
  switch ($path) {
    case 'admin/structure/organigrams':
      $help = t('Organigrams represent visualizations of hierarchies in organizations. An organigram contains multiple items which can be related in various ways to each other.');
      $help .= '<p>';
      $help .= t('Organigrams have multiple display options:');
      $help .= '<ol>';
      $help .= '<li>' . t('<strong>Dedicated page</strong><br />A dedicated page is available at <i>/organigram/%machine_name</i>.') . '</li>';
      $help .= '<li>' . t('<strong>Block</strong><br />The organigram blocks can be found in the !block_list.', array(
        '!block_list' => l(t('block list'), 'admin/structure/block'),
      )) . '</li>';
      $help .= '<li>' . t('<strong>Token</strong> (requires <a href="@token_filter">Token filter</a>)<br />Tokens can be used to insert organigrams in content fields. The token names are displayed beneath the names in this list and look like this: <i>[organigrams:%machine_name]</i>. Just copy and paste this token in your content to insert the organigram.', array(
        '@token_filter' => 'https://www.drupal.org/project/token_filter',
      )) . '</li>';
      $help .= '</ol></p>';
      return '<p>' . $help . '</p>';
  }
}

/**
 * Implements hook_library().
 */
function organigrams_library() {
  $libraries = array();

  // Orgchart.
  $libraries['orgchart'] = array(
    'title' => 'Orgchart',
    'version' => '1.14',
    'js' => array(
      drupal_get_path('module', 'organigrams') . '/libraries/orgchart/orgchart.js' => array(),
    ),
    'dependencies' => array(
      // Require jQuery core.
      array(
        'system',
        'jquery',
      ),
    ),
  );
  return $libraries;
}

/**
 * Implements hook_libraries_info().
 */
function organigrams_libraries_info() {
  $libraries = array();

  // Explorer Canvas.
  $libraries['excanvas'] = array(
    'name' => 'ExplorerCanvas',
    'vendor url' => 'https://github.com/arv/explorercanvas',
    'download url' => 'https://github.com/arv/ExplorerCanvas/archive/aa989ea9d9bac748638f7c66b0fc88e619715da6.zip',
    'version' => 'aa989ea9d9bac748638f7c66b0fc88e619715da6',
    'files' => array(
      'js' => array(
        'excanvas.js',
      ),
    ),
  );

  // Colorpicker.
  $libraries['colorpicker'] = array(
    'name' => 'ColorPicker',
    'vendor url' => 'https://github.com/evoluteur/colorpicker/tree/233e15e4368b0d1eb30f8036a1f5970f09e8ed9e',
    'download url' => 'https://github.com/evoluteur/colorpicker/archive/233e15e4368b0d1eb30f8036a1f5970f09e8ed9e.zip',
    'version' => '233e15e4368b0d1eb30f8036a1f5970f09e8ed9e',
    'files' => array(
      'js' => array(
        'js/evol-colorpicker.min.js',
      ),
      'css' => array(
        'css/evol-colorpicker.min.css',
      ),
    ),
  );
  return $libraries;
}

/**
 * Implements hook_theme().
 */
function organigrams_theme() {
  return array(
    'organigrams_form_overview_organigrams' => array(
      'render element' => 'form',
      'path' => drupal_get_path('module', 'organigrams') . '/theme',
      'file' => 'organigrams.theme.inc',
    ),
    'organigrams_form_overview_organigrams_items' => array(
      'render element' => 'form',
      'path' => drupal_get_path('module', 'organigrams') . '/theme',
      'file' => 'organigrams.theme.inc',
    ),
    'organigrams' => array(
      'render element' => 'elements',
      'base hook' => 'entity',
      'template' => 'organigrams',
      'path' => drupal_get_path('module', 'organigrams') . '/theme',
    ),
  );
}

/**
 * Get a value indicating whether the user perform the operation.
 *
 * @param string $operation
 *   An operation to perform on the organigram. Valid values are view, edit and
 *   delete.
 * @param mixed $object
 *   An organigram ID, machine name or object on which the operation will be
 *   performed.
 * @param mixed $account
 *   The account to check, if not given use currently logged in user.
 *
 * @return bool
 *   TRUE if the user has permission to perform the operation, otherwise FALSE.
 */
function organigrams_user_access($operation, $object, $account = NULL) {
  static $valid_operations = array(
    'view',
    'edit',
    'delete',
  );

  // Check if the user is not an administrator and validate the operation.
  if (!($granted = user_access('administer organigrams', $account)) && in_array($operation, $valid_operations)) {

    // If the $object argument is a string.
    if (is_string($object)) {

      // Then assume its an organigram machine name and try to load the
      // organigram.
      $object = organigrams_machine_name_load($object);
    }
    elseif (is_numeric($object)) {

      // Then assume its an organigram ID and try to load the organigram.
      $object = organigrams_load($object);
    }

    // Check if the operation describes a view operation.
    if ($operation == 'view' && $object->status) {

      // Check for the access content access right.
      $granted = user_access('access content', $account);
    }
    else {

      // The view operation is denied so check if the user has edit access.
      if ($operation == 'view') {
        $operation = 'edit';
      }

      // Get the machine name.
      $machine_name = isset($object->machine_name) ? $object->machine_name : $object->organigrams_machine_name;

      // A user which has not the correct permission will be evaluated for a
      // specific organigram permission. Retrieve a value indicating whether the
      // current user has permission to perform the specified operation on the
      // organigram.
      $granted = user_access("{$operation} organigram {$machine_name}", $account);
    }
  }
  return $granted;
}

/**
 * Get the organigrams name which can be used as page title.
 *
 * @param object $organigrams
 *   An organigrams entity.
 *
 * @return string
 *   A string containing the organigrams name.
 */
function organigrams_title($organigrams) {
  return $organigrams->name;
}

/**
 * Get the organigrams item name which can be used as page title.
 *
 * @param object $organigrams_item
 *   An organigrams item entity.
 *
 * @return string
 *   A string containing the organigrams item name.
 */
function organigrams_item_title($organigrams_item) {
  return $organigrams_item->name;
}

/**
 * Access callback for the organigrams entities.
 *
 * @param string $op
 *   An operation to perform on the organigram. Valid values are view, edit and
 *   delete.
 * @param object $entity
 *   An organigrams entity on which the operation will be performed.
 * @param mixed $account
 *   The account to check, if not given use currently logged in user.
 *
 * @return bool
 *   TRUE if the user has permission to perform the operation, otherwise FALSE.
 */
function organigrams_entity_access($op, $entity, $account = NULL) {

  // Determine whether the given account has access to the entity for the
  // specified operation.
  return organigrams_user_access($op, $entity, $account);
}

/**
 * Entity API property setter callback organigrams item.
 *
 * @param object $organigrams_item
 *   An organigrams item entity.
 * @param string $name
 *   A string containing the property name.
 * @param mixed $value
 *   A string or integer to set as property value.
 *
 * @return mixed
 *   An organigrams ID.
 */
function organigrams_metadata_organigrams_item_setter($organigrams_item, $name, $value) {

  // Evaluate the property name.
  switch ($name) {
    case 'organigram':

      // Make sure to also update the organigrams bundle key.
      $organigrams = organigrams_load($value);
      $organigrams_item->organigrams_machine_name = $organigrams->machine_name;
      return $organigrams_item->oid = $value;
    case 'parent':
      return $organigrams_item->parent = $value;
  }
}

/**
 * Generate an renderable item list array for the specified organigram.
 *
 * @param object $organigram
 *   An organigrams entity.
 * @param mixed $langcode
 *   The language in which the organigram needs to be rendered.
 *
 * @return array
 *   A renderable array for the specified organigram if found, otherwise NULL.
 */
function organigrams_compose_organigrams($organigram, $langcode = NULL) {

  // Default output.
  $output = array();

  // Validate loaded organigram.
  if (!$organigram) {
    return $output;
  }

  // Construct the orgchart settings.
  $organigram_settings = array(
    'organigram_settings' => (object) array(
      'canvas_width' => $organigram->canvas_width,
      'canvas_height' => $organigram->canvas_height,
      'center' => $organigram->center,
      'fit' => $organigram->fit,
      'node_width' => $organigram->node_width,
      'node_height' => $organigram->node_height,
      'top_radius' => $organigram->top_radius,
      'bottom_radius' => $organigram->bottom_radius,
      'shadow_offset' => $organigram->shadow_offset,
      'horizontal_space' => $organigram->horizontal_space,
      'vertical_space' => $organigram->vertical_space,
      'horizontal_offset' => $organigram->horizontal_offset,
      'line_color' => $organigram->line_color,
      'border_color' => $organigram->border_color,
      'border_color_hover' => $organigram->border_color_hover,
      'background_color' => $organigram->background_color,
      'background_color_hover' => $organigram->background_color_hover,
      'font_color' => $organigram->font_color,
      'font_color_hover' => $organigram->font_color_hover,
      'font_name' => $organigram->font_name,
      'font_size' => $organigram->font_size,
      'line_height' => $organigram->line_height,
      'vertical_alignment' => $organigram->vertical_alignment,
    ),
    'nodes' => array(),
  );

  // Retrieve the organigram tree.
  $organigram_tree = organigrams_get_tree($organigram->oid, 0, NULL, TRUE);

  // Validate if the organigram has any items.
  if (empty($organigram_tree)) {
    return $output;
  }

  // Create a hierarchical list from all organigram items.
  $hierarchical_list = array();

  // Iterate through the organigram tree.
  foreach ($organigram_tree as $tree_item) {

    // Set the parent ID.
    $parent = 0;
    if (!empty($tree_item->parent)) {
      $parent = $tree_item->parent;
    }

    // Create a new array for this parent if it doesn't exist.
    if (!isset($hierarchical_list[$parent])) {
      $hierarchical_list[$parent] = array();
    }

    // Add the item to this parent.
    $hierarchical_list[$parent][] = $tree_item;
  }

  // Generate the list. This will be displayed if the JavaScript cannot be
  // loaded and is used as data source for the orgchart library.
  $output = array(
    '#theme' => 'item_list',
    '#type' => 'ul',
    '#items' => organigrams_generate_items_list($hierarchical_list),
  );

  // Include the excanvas library if it exists.
  $output['#attached']['libraries_load'][] = array(
    'excanvas',
  );

  // Include the orgchart library.
  $output['#attached']['library'][] = array(
    'organigrams',
    'orgchart',
  );

  // Include the organigram content loader.
  $output['#attached']['js'][] = drupal_get_path('module', 'organigrams') . '/js/organigrams.js';

  // Add the organigram to the organigrams list.
  $output['#attached']['js'][] = array(
    'data' => array(
      'organigrams' => array(
        'organigrams' => array(
          $organigram->unique_id => $organigram_settings,
        ),
      ),
    ),
    'type' => 'setting',
  );
  return $output;
}

/**
 * Create a nested array with items to be used for generating an item list.
 *
 * The orgchart library will extract the node data from the list item
 * attributes.
 *
 * @param array $hierarchical_list
 *    An array containing all organigrams items sorted by parent.
 * @param int $parent
 *    The parent ID of an organigrams item.
 *
 * @return array
 *    Nested array ready for the item list theme.
 */
function organigrams_generate_items_list($hierarchical_list = array(), $parent = 0) {
  $ul_list = array();
  if (isset($hierarchical_list[$parent])) {
    foreach ($hierarchical_list[$parent] as $item) {

      // Create the HTML content for the li.
      $html_name = str_replace('[br]', '<br />', check_plain($item->name));
      if (!empty($item->url)) {
        $attributes = array(
          'html' => TRUE,
          'attributes' => array(),
        );
        if (strtolower(substr($item->url, 0, 4)) == 'http') {
          $attributes['attributes']['target'] = '_blank';
        }
        $html_name = l($html_name, $item->url, $attributes);
      }
      $ul_list[] = array(
        'data' => $html_name,
        'children' => organigrams_generate_items_list($hierarchical_list, $item->iid),
        'item_id' => check_plain($item->iid),
        'parent' => empty($item->parent) ? '' : check_plain($item->parent),
        'position' => check_plain($item->position),
        'text' => decode_entities(check_plain($item->name)),
        'bold_border' => check_plain($item->bold_border),
        'url' => decode_entities(check_plain($item->url)),
        'border_color' => check_plain($item->border_color),
        'border_color_hover' => check_plain($item->border_color_hover),
        'background_color' => check_plain($item->background_color),
        'background_color_hover' => check_plain($item->background_color_hover),
        'font_color' => check_plain($item->font_color),
        'font_color_hover' => check_plain($item->font_color_hover),
        'image_url' => check_plain($item->image_url),
        'image_alignment' => check_plain($item->image_alignment),
      );
    }
  }
  return $ul_list;
}

/**
 * Get a list of organigram names.
 *
 * @return array
 *   An array of organigram ids, names and machine names, keyed by machine name.
 */
function organigrams_get_names() {

  // Retrieve all organigrams.
  $names = db_query('SELECT name, machine_name, oid FROM {organigrams_data}')
    ->fetchAllAssoc('machine_name');

  // Return the organigram names.
  return $names;
}

/**
 * Get a list of organigrams objects.
 *
 * @return array
 *   An array of organigrams objects, keyed by the organigrams ID.
 */
function organigrams_get_organigrams() {

  // Load all organigrams objects and return the list.
  return organigrams_load_multiple(FALSE, array());
}

/**
 * Create a hierarchical representation of an organigram.
 *
 * @param int $oid
 *   An organigrams ID.
 * @param int $parent
 *   An organigrams item ID under which to generate the tree. If 0, generate the
 *   tree for the entire organigrams.
 * @param mixed $max_depth
 *   The number of levels of the tree to return. Leave NULL to return all
 *   levels.
 * @param bool $load_entities
 *   If TRUE, a full entity load will occur on the organigrams item objects.
 *   Otherwise they are partial objects queried directly from the
 *   {organigrams_item_data} table to save execution time and memory consumption
 *   when listing large numbers of organigrams items. Defaults to FALSE.
 *
 * @return array
 *   An array of all organigrams item objects in the tree. Each organigrams item
 *   object is extended to have "depth" attribute in addition to its normal
 *   ones. Results are statically cached. organigrams item objects will be
 *   partial or complete depending on the $load_entities parameter.
 */
function organigrams_get_tree($oid, $parent = 0, $max_depth = NULL, $load_entities = FALSE) {

  // Retrieve the static cache.
  $children =& drupal_static(__FUNCTION__, array());
  $parents =& drupal_static(__FUNCTION__ . ':parents', array());
  $organigrams_items =& drupal_static(__FUNCTION__ . ':organigrams_items', array());

  // Check if the oid is cached.
  if (!isset($children[$oid])) {

    // Initialize the arrays for the given oid.
    $children[$oid] = array();
    $parents[$oid] = array();
    $organigrams_items[$oid] = array();

    // Construct hierarchy query.
    $query = db_select('organigrams_item_data', 'oid');
    $result = $query
      ->addTag('translatable')
      ->addTag('organigrams_item_access')
      ->fields('oid')
      ->condition('oid.oid', $oid)
      ->orderBy('oid.weight')
      ->orderBy('oid.name')
      ->execute();

    // Iterate through the result set.
    foreach ($result as $organigrams_item) {

      // If no array is initialized then initialize.
      if (($organigrams_item_children =& $children[$oid][$organigrams_item->parent]) === NULL) {
        $organigrams_item_children = array();
      }

      // If not initialized then initialize.
      if (($organigrams_item_parents =& $parents[$oid][$organigrams_item->iid]) === NULL) {
        $organigrams_item_parents = array();
      }

      // Add the hierarchy.
      $organigrams_item_children[] = $organigrams_item->iid;
      $organigrams_item_parents[] = $organigrams_item->parent;
      $organigrams_items[$oid][$organigrams_item->iid] = $organigrams_item;
    }
  }

  // Load full entities, if necessary. The entity controller statically caches
  // the results.
  if ($load_entities) {
    $organigrams_item_entities = organigrams_item_load_multiple(array_keys($organigrams_items[$oid]));
  }

  // Determine the max depth.
  $max_depth = isset($max_depth) ? $max_depth : count($children[$oid]);

  // Initialize the tree.
  $tree = array();

  // Keeps track of the parents we have to process, the last entry is used for
  // the next processing step.
  $process_parents = array(
    $parent,
  );

  // Loop over the parents.
  while (count($process_parents)) {

    // Pop a parent from the parents list.
    $parent = array_pop($process_parents);

    // The number of parents determines the current depth.
    $depth = count($process_parents);

    // Check if the current depth is not passed the max depth.
    if ($max_depth > $depth && !empty($children[$oid][$parent])) {
      $has_children = FALSE;
      $child = current($children[$oid][$parent]);
      do {
        if (empty($child)) {
          break;
        }

        // Retrieve the organigrams item. This can be a queried entity or a
        // fully loaded entity depending on the load_entities value.
        $organigrams_item = $organigrams_items[$oid][$child];
        if ($load_entities && isset($organigrams_item_entities[$child])) {
          $organigrams_item = $organigrams_item_entities[$child];
        }

        // Add the depth as a property.
        $organigrams_item->depth = $depth;

        // Add the organigrams item to the tree.
        $tree[] = $organigrams_item;

        // Check if the organigrams item has children.
        if (!empty($children[$oid][$organigrams_item->iid])) {

          // Indicate that new children were found.
          $has_children = TRUE;

          // We have to continue with this parent later.
          $process_parents[] = $parent;

          // Use the current organigrams item as parent for the next iteration.
          $process_parents[] = $organigrams_item->iid;

          // Reset pointers for child lists.
          reset($children[$oid][$organigrams_item->iid]);

          // Move pointer so that we get the current organigrams item the next
          // time.
          next($children[$oid][$parent]);
          break;
        }
      } while ($child = next($children[$oid][$parent]));

      // Check if the current iteration resulted in new children.
      if (!$has_children) {

        // We processed all terms in this hierarchy-level, reset pointer
        // so that this function works the next time it gets called.
        reset($children[$oid][$parent]);
      }
    }
  }

  // Return the constructed tree.
  return $tree;
}

/**
 * Get an organigrams object matching an organigrams machine name.
 *
 * @param string $name
 *   An organigrams machine name.
 *
 * @return mixed
 *   An organigrams object with all of its metadata if exists, otherwise FALSE.
 *   Results are statically cached.
 */
function organigrams_machine_name_load($name) {

  // Retrieve the organigrams containing the name.
  $organigrams = organigrams_load_multiple(FALSE, array(
    'machine_name' => $name,
  ));

  // Return the first entry.
  return reset($organigrams);
}

/**
 * Add an index to a machine name if it already exists to make sure its unique.
 *
 * @param string $name
 *   An organigrams machine name.
 *
 * @return string
 *   A unique organigrams machine name.
 */
function organigrams_check_machine_name($name) {
  $index = 0;
  $new_name = $name;
  while (organigrams_machine_name_load($new_name)) {
    $new_name = $name . '_' . $index++;
  }
  return $new_name;
}

/**
 * Try to map a string to an existing organigrams item, as for glossary use.
 *
 * @param string $name
 *   An organigrams item name to search for.
 *
 * @return array
 *   An array of matching organigrams item objects.
 */
function organigrams_get_item_by_name($name) {
  return organigrams_item_load_multiple(FALSE, array(
    'name' => trim($name),
  ));
}

/**
 * Get an organigrams object matching the organigrams ID.
 *
 * @param int $oid
 *   An organigrams ID.
 *
 * @return object
 *   An organigrams object if exists, otherwise FALSE. Results are statically
 *   cache.
 */
function organigrams_load($oid) {

  // Initialize the organigrams to FALSE.
  $organigrams = FALSE;

  // Validate oid argument.
  if (is_numeric($oid)) {

    // Load the organigrams.
    $organigrams = organigrams_load_multiple(array(
      $oid,
    ), array());

    // Assign the first entry to organigrams.
    $organigrams = reset($organigrams);
  }

  // Return the organigrams.
  return $organigrams;
}

/**
 * Get an organigrams item object matching the organigrams item ID.
 *
 * @param int $iid
 *   An organigrams item ID.
 *
 * @return object
 *   An organigrams item object if exists, otherwise FALSE. Results are
 *   statically cached.
 */
function organigrams_item_load($iid) {

  // Initialize the organigrams item to FALSE.
  $organigrams_item = FALSE;

  // Validate iid argument.
  if (is_numeric($iid)) {

    // Load the organigrams item.
    $organigrams_items = organigrams_item_load_multiple(array(
      $iid,
    ), array());

    // Assign the first entry to organigrams_item.
    $organigrams_item = reset($organigrams_items);
  }

  // Return the organigrams item.
  return $organigrams_item;
}

/**
 * Load multiple organigrams based on certain conditions.
 *
 * This function should be used whenever you need to load more than one
 * organigram from the database. organigrams are loaded into memory and will not
 * require database access if loaded again during the same page request.
 *
 * @param array $oids
 *   An array of organigrams IDs.
 * @param array $conditions
 *   An associative array of conditions on the {organigrams} table, where the
 *   keys are the database fields and the values are the values those fields
 *   must have.
 *
 * @return array
 *   An array of organigrams objects, keyed by oid.
 */
function organigrams_load_multiple($oids = array(), $conditions = array()) {

  // Retrieve an array of organigrams objects using the specified conditions and
  // return the result.
  return entity_load('organigrams', $oids, $conditions);
}

/**
 * Load multiple organigrams items based on certain conditions.
 *
 * This function should be used whenever you need to load more than one
 * organigrams item from the database. organigrams items are loaded into memory
 * and will not require database access if loaded again during the same page
 * request.
 *
 * @param array $iids
 *   An array of organigrams item IDs.
 * @param array $conditions
 *   An associative array of conditions on the {organigrams} table, where the
 *   keys are the database fields and the values are the values those fields
 *   must have.
 *
 * @return array
 *   An array of organigrams item objects, indexed by iid.
 */
function organigrams_item_load_multiple($iids = array(), $conditions = array()) {

  // Retrieve an array of organigrams item objects using the specified
  // conditions and return the result.
  return entity_load('organigrams_item', $iids, $conditions);
}

/**
 * Save an organigram given an organigrams object.
 *
 * @param object $organigrams
 *   An organigrams object.
 *
 * @return int
 *   The SAVED_NEW or SAVED_UPDATED if successful, otherwise NULL.
 */
function organigrams_save($organigrams) {

  // Prevent leading and trailing spaces in organigrams names.
  $organigrams->name = trim($organigrams->name);

  // Load the stored entity, if any.
  if (!empty($organigrams->oid)) {

    // If the original property is not set.
    if (!isset($organigrams->original)) {

      // Load an unchanged organigrams object.
      $organigrams->original = entity_load_unchanged('organigrams', $organigrams->oid);
    }
    $organigrams->old_machine_name = $organigrams->original->machine_name;
  }

  // If the module property is missing.
  if (!isset($organigrams->module)) {

    // Then use the 'organigrams' as creator module.
    $organigrams->module = 'organigrams';
  }

  // Allow modules to perform logic on presave.
  field_attach_presave('organigrams', $organigrams);
  module_invoke_all('organigrams_presave', $organigrams);
  module_invoke_all('entity_presave', $organigrams, 'organigrams');

  // Initialize the status variable.
  $status = NULL;

  // If the oid and name is not empty.
  if (!empty($organigrams->oid) && !empty($organigrams->name)) {

    // Write the organigrams to the DB.
    $status = drupal_write_record('organigrams_data', $organigrams, 'oid');

    // If the organigrams machine name changed.
    if ($organigrams->old_machine_name != $organigrams->machine_name) {

      // Rename the field bundle.
      field_attach_rename_bundle('organigrams_item', $organigrams->old_machine_name, $organigrams->machine_name);
    }

    // Allow modules to perform action on update.
    field_attach_update('organigrams', $organigrams);
    module_invoke_all('organigrams_update', $organigrams);
    module_invoke_all('entity_update', $organigrams, 'organigrams');
  }
  elseif (empty($organigrams->oid)) {

    // Write the organigrams to the DB.
    $status = drupal_write_record('organigrams_data', $organigrams);

    // Attach the field bundle.
    field_attach_create_bundle('organigrams_item', $organigrams->machine_name);

    // Allow modules to perform action on insert.
    field_attach_insert('organigrams', $organigrams);
    module_invoke_all('organigrams_insert', $organigrams);
    module_invoke_all('entity_insert', $organigrams, 'organigrams');
  }

  // Remove the original and old_machine_name property.
  unset($organigrams->original);
  unset($organigrams->old_machine_name);

  // Clear cache.
  cache_clear_all();

  // Request entity cache reset for the given oid.
  entity_get_controller('organigrams')
    ->resetCache(array(
    $organigrams->oid,
  ));

  // Return the operation status.
  return $status;
}

/**
 * Save an organigrams item given an organigrams item object.
 *
 * @param object $organigrams_item
 *   An organigrams item object.
 *
 * @return int
 *   The SAVED_NEW or SAVED_UPDATED if successful, otherwise NULL.
 */
function organigrams_item_save($organigrams_item) {

  // Prevent leading and trailing spaces in the organigrams item name.
  $organigrams_item->name = trim($organigrams_item->name);

  // If the organigrams machine name is not set, then load the organigrams and
  // assign the machine name.
  if (!isset($organigrams_item->organigrams_machine_name)) {

    // Load the organigrams using the organigrams ID.
    $organigrams = organigrams_load($organigrams_item->oid);

    // Assign the organigrams_machine_name property to the organigrams item.
    $organigrams_item->organigrams_machine_name = $organigrams->machine_name;
  }

  // Load the stored entity, if any.
  if (!empty($organigrams_item->iid) && !isset($organigrams_item->original)) {

    // Load the unchanged entity object.
    $organigrams_item->original = entity_load_unchanged('organigrams_item', $organigrams_item->iid);
  }

  // Allow modules to perform logic on presave.
  field_attach_presave('organigrams_item', $organigrams_item);
  module_invoke_all('organigrams_item_presave', $organigrams_item);
  module_invoke_all('entity_presave', $organigrams_item, 'organigrams_item');

  // Perform insert is no iid isset.
  if (empty($organigrams_item->iid)) {

    // Save operation (used for hooks).
    $op = 'insert';

    // Write organigrams item to DB.
    $status = drupal_write_record('organigrams_item_data', $organigrams_item);
    field_attach_insert('organigrams_item', $organigrams_item);
  }
  else {

    // Save operation (used for hooks).
    $op = 'update';

    // Write organigrams item to DB.
    $status = drupal_write_record('organigrams_item_data', $organigrams_item, 'iid');
    field_attach_update('organigrams_item', $organigrams_item);
  }

  // Reset the organigrams item cache.
  organigrams_items_static_reset();

  // Allow modules to react upon insert or update.
  module_invoke_all("organigrams_item_{$op}", $organigrams_item);
  module_invoke_all("entity_{$op}", $organigrams_item, 'organigrams_item');

  // Remove the original property.
  unset($organigrams_item->original);

  // Return the operation status.
  return $status;
}

/**
 * Delete an organigram given the organigrams ID.
 *
 * @param int $oid
 *   An integer representing an organigrams ID.
 *
 * @return int
 *   The SAVED_DELETED if successful, otherwise NULL.
 *
 * @throws \Exception
 */
function organigrams_delete($oid) {

  // Retrieve the organigrams object.
  $organigrams = organigrams_load($oid);

  // Start a transaction.
  $transaction = db_transaction();
  try {

    // Retrieve all the organigrams items assigned to the current organigrams.
    $result = db_query('SELECT iid FROM {organigrams_item_data} WHERE oid = :oid', array(
      ':oid' => $oid,
    ))
      ->fetchCol();

    // Iterate through the result set.
    foreach ($result as $iid) {

      // Remove the organigrams item.
      organigrams_item_delete($iid);
    }

    // Create delete statement.
    db_delete('organigrams_data')
      ->condition('oid', $oid)
      ->execute();

    // Remove the field bundle.
    field_attach_delete_bundle('organigrams_item', $organigrams->machine_name);

    // Allow modules to perform actions after deletion.
    module_invoke_all('organigrams_delete', $organigrams);
    module_invoke_all('entity_delete', $organigrams, 'organigrams');

    // Clear cache.
    cache_clear_all();

    // Request entity cache reset for the given oid.
    entity_get_controller('organigrams')
      ->resetCache();

    // Return status deleted.
    return SAVED_DELETED;
  } catch (Exception $ex) {

    // Rollback DB modifications.
    $transaction
      ->rollback();

    // Log to watchdog.
    watchdog_exception('organigrams', $ex);

    // Rethrow the exception.
    throw $ex;
  }
}

/**
 * Delete an organigrams item.
 *
 * @param object $iid
 *   An organigrams item.
 *
 * @throws \Exception
 */
function organigrams_item_delete($iid) {

  // Start a transaction.
  $transaction = db_transaction();
  try {

    // Create iid collection.
    $iids = array(
      $iid,
    );
    while (!empty($iids)) {

      // Initialize orphans list.
      $orphans = array();

      // Iterate through the iids.
      foreach ($iids as $iid) {

        // Retrieve children for the current iid.
        $orphans = array_keys(organigrams_item_get_children($iid));

        // Check if the organigrams item exists.
        if (($organigrams_item = organigrams_item_load($iid)) !== NULL) {

          // Remove the organigrams item.
          db_delete('organigrams_item_data')
            ->condition('iid', $iid)
            ->execute();

          // Remove the bundled data for the specified entity.
          field_attach_delete('organigrams_item', $organigrams_item);

          // Allow modules to act upon the delete action.
          module_invoke_all('organigrams_item_delete', $organigrams_item);
          module_invoke_all('entity_delete', $organigrams_item, 'organigrams_item');

          // Reset the organigrams item cache.
          organigrams_items_static_reset();
        }
      }

      // Assign the orphans list to the iids list.
      $iids = $orphans;
    }
  } catch (Exception $ex) {

    // Undo DB changes.
    $transaction
      ->rollback();

    // Log exception.
    watchdog_exception('organigrams', $ex);

    // Rethrow the exception.
    throw $ex;
  }
}

/**
 * Finds all children of an organigrams item ID.
 *
 * @param int $iid
 *   An organigrams item ID.
 *
 * @return array
 *   An array of organigrams item objects which are the children of the
 *   organigrams item.
 */
function organigrams_item_get_children($iid) {

  // Retrieve static cache.
  $children =& drupal_static(__FUNCTION__, array());

  // Validate iid argument and check if the static cache has an entry.
  if ($iid && !isset($children[$iid])) {

    // Retrieve organigrams item children.
    $query = db_select('organigrams_item_data', 'oid');
    $query
      ->addTag('organigrams_item_access');
    $query
      ->addField('oid', 'iid');
    $query
      ->condition('oid.parent', $iid);
    $query
      ->orderBy('oid.weight');
    $query
      ->orderBy('oid.name');
    $iids = $query
      ->execute()
      ->fetchCol();

    // Load the full object for each organigrams item and save to static cache.
    $children[$iid] = organigrams_item_load_multiple($iids);
  }

  // Return the static cached version.
  return isset($children[$iid]) ? $children[$iid] : array();
}

/**
 * Find parent of a given organigrams item ID.
 *
 * @param int $iid
 *   An organigrams item ID.
 *
 * @return mixed
 *   An organigrams item object if the parent exists, otherwise NULL.
 */
function organigrams_item_get_parent($iid) {
  $parent_organigrams_item = NULL;

  // Try to load the organigrams item and check if the parent contains a value.
  // (Remember 0 is no parent).
  if (($organigrams_item = organigrams_item_load($iid)) !== NULL && !empty($organigrams_item->parent)) {

    // Try to load the organigrams item parent.
    $parent_organigrams_item = organigrams_item_load($organigrams_item->parent);
  }
  return $parent_organigrams_item;
}

/**
 * Generate a list of suitable parents for the given organigrams item.
 *
 * This function is suitable for selection form elements.
 *
 * @param int $iid
 *   An organigrams item ID.
 * @param int $oid
 *   An organigrams ID.
 *
 * @return array
 *   An associative array of parents, keyed by the organigrams item ID and the
 *   name as value.
 */
function organigrams_item_get_suitable_parents_options($iid, $oid) {

  // Initialize the parent relation options.
  $parent_relation_options = array();

  // Retrieve the children.
  $children = organigrams_get_tree($oid, $iid);

  // Construct excluded iids.
  $excluded_iids = array();
  foreach ($children as $child) {
    $excluded_iids[] = $child->iid;
  }
  $excluded_iids[] = $iid;

  // Iterate through the organigrams tree.
  foreach (organigrams_get_tree($oid) as $tree_item) {

    // Do not allow the excluded iids as parent.
    if (!in_array($tree_item->iid, $excluded_iids)) {

      // Add organigrams item name to the parent options.
      $parent_relation_options[$tree_item->iid] = str_repeat('-', $tree_item->depth) . filter_xss_admin($tree_item->name);
    }
  }

  // Return the suitable parent options.
  return $parent_relation_options;
}

/**
 * Import organigram items in an existing organigram.
 *
 * @param int $oid
 *   An organigram ID.
 * @param string $import
 *   A JSON string containing organigram items to import.
 *
 * @return bool|string
 *   TRUE if the import succeeded, otherwise a string containing an error
 *   message.
 *
 * @throws \Exception
 */
function organigrams_import_items($oid, $import) {

  // Load the organigram to import the items into.
  $organigram = organigrams_load($oid);

  // Check if the organigram exists.
  if (empty($organigram)) {
    watchdog('organigrams', 'Failed importing organigram items because no organigram was found.');
    return t('Failed importing organigram items because no organigram was found.');
  }

  // Check if we have any import data.
  if (empty($import)) {
    watchdog('organigrams', 'Failed importing organigram items because no import was found.');
    return t('Failed importing organigram items because no import was found.');
  }

  // Store the old data for rollback purposes.
  $old_data = organigrams_get_tree($oid, 0, NULL, TRUE);

  // Remove all old data from the organigram.
  foreach ($old_data as $old_item) {
    organigrams_item_delete($old_item->iid);
  }

  // This array stores items which need to be saved again when a parent has
  // changed.
  $needs_resave = array();

  // Iterate through the new data.
  foreach ($import as $new_item) {

    // Store the original item ID.
    $orig_iid = $new_item->iid;

    // If this item was marked for resave, remove it from the array because it
    // gets saved now.
    if (isset($needs_resave[$orig_iid])) {
      unset($needs_resave[$orig_iid]);
    }

    // Unset the item ID. It will receive a new ID when saving to prevent
    // duplicate IDs in the database.
    unset($new_item->iid);

    // Set the organigram ID and machine name to the organigram we are importing
    // into.
    $new_item->oid = $oid;
    $new_item->organigrams_machine_name = $organigram->machine_name;

    // Save the new item.
    $result = organigrams_item_save($new_item);

    // If saving failed somehow, abort and call this function again with the
    // old data to restore the organigram.
    if (!$result) {
      watchdog('organigrams', 'An error occurred importing item %name. Old values are restored.', array(
        '%name' => $new_item->name,
      ));
      organigrams_import_items($oid, $old_data);
      return t('An error occurred importing item %name. Old values are restored.', array(
        '%name' => $new_item->name,
      ));
    }

    // On saving, an item receives a new ID. Iterate once more through the
    // import data to update the parent IDs referencing to this newly saved
    // item.
    foreach ($import as $key => $value) {
      if ($value->parent == $orig_iid) {
        $import[$key]->parent = $new_item->iid;

        // Add this item to the resave array to make sure its new data gets
        // saved even if this item already has been imported.
        $needs_resave[$value->iid] = $import[$key];
      }
    }
  }

  // Resave the items in the resave array.
  if (!empty($needs_resave)) {
    foreach ($needs_resave as $item) {
      organigrams_item_save($item);
    }
  }
  watchdog('organigrams', 'Successfully imported items in organigram %name', array(
    '%name' => $organigram->name,
  ));
  return TRUE;
}

/**
 * Implements hook_token_info().
 */
function organigrams_token_info() {

  // Define the token type 'organigrams'.
  $types['organigrams'] = array(
    'name' => t('Organigrams'),
    'description' => t('Tokens for inserting organigram blocks.'),
  );

  // Define an empty array.
  $organigrams = array();

  // Add tokens for all organigrams.
  foreach (organigrams_get_names() as $organigram) {
    $organigrams[$organigram->machine_name] = array(
      'name' => t('Organigram: !organigram', array(
        '!organigram' => $organigram->name,
      )),
      'description' => t('Insert the organigram !organigram.', array(
        '!organigram' => $organigram->name,
      )),
    );
  }
  return array(
    'types' => $types,
    'tokens' => array(
      'organigrams' => $organigrams,
    ),
  );
}

/**
 * Implements hook_tokens().
 */
function organigrams_tokens($type, $tokens, array $data = array(), array $options = array()) {
  $replacements = array();

  // Replace the organigrams tokens with actual organigrams.
  if ($type == 'organigrams') {
    foreach ($tokens as $name => $original) {
      $organigram = organigrams_machine_name_load($name);
      if (!empty($organigram)) {
        $organigram_renderable_array = entity_view('organigrams', array(
          $organigram,
        ), 'organigram_block');
        $replacements[$original] = render($organigram_renderable_array);
      }
    }
  }
  return $replacements;
}

/**
 * Clear all static cache variables for organigrams items.
 */
function organigrams_items_static_reset() {
  drupal_static_reset('organigrams_item_get_children');
  drupal_static_reset('organigrams_get_tree');
  drupal_static_reset('organigrams_get_tree:parents');
  drupal_static_reset('organigrams_get_tree:organigrams_items');
}

/*
 * Controller classes for the declared entities.
 */

/**
 * Controller class for organigrams.
 *
 * This extends the DrupalDefaultEntityController class, adding required
 * special handling for organigrams objects.
 */
class OrganigramsController extends EntityAPIController {

  /**
   * Builds the query to load the entity.
   *
   * @param array $ids
   *   An array of entity IDs, or FALSE to load all entities.
   * @param array $conditions
   *   An array of conditions in the form 'field' => $value.
   * @param mixed $revision_id
   *   The ID of the revision to load, or FALSE if this query is asking for the
   *   most current revision(s).
   *
   * @return SelectQuery
   *   A SelectQuery object for loading the entity.
   */
  protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) {
    $query = parent::buildQuery($ids, $conditions, $revision_id);
    $query
      ->addTag('translatable');
    $query
      ->orderBy('base.weight');
    $query
      ->orderBy('base.name');
    return $query;
  }

}

/**
 * Controller class for organigrams items.
 *
 * This extends the DrupalDefaultEntityController class. Only alternation is
 * that we match the condition on organigrams item name case-independently.
 */
class OrganigramsItemController extends EntityAPIController {

  /**
   * Builds the query to load the entity.
   *
   * @param array $ids
   *   An array of entity IDs, or FALSE to load all entities.
   * @param array $conditions
   *   An array of conditions in the form 'field' => $value.
   * @param mixed $revision_id
   *   The ID of the revision to load, or FALSE if this query is asking for the
   *   most current revision(s).
   *
   * @return SelectQuery
   *   A SelectQuery object for loading the entity.
   */
  protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) {
    $query = parent::buildQuery($ids, $conditions, $revision_id);
    $query
      ->addTag('translatable');
    $query
      ->addTag('organigrams_item_access');

    // When name is passed as a condition use LIKE.
    if (isset($conditions['name'])) {
      $query_conditions =& $query
        ->conditions();
      foreach ($query_conditions as $key => $condition) {
        if ($condition['field'] == 'base.name') {
          $query_conditions[$key]['operator'] = 'LIKE';
          $query_conditions[$key]['value'] = db_like($query_conditions[$key]['value']);
        }
      }
    }

    // Add the machine name field from the {organigrams} table.
    $query
      ->innerJoin('organigrams_data', 'o', 'base.oid = o.oid');
    $query
      ->addField('o', 'machine_name', 'organigrams_machine_name');
    return $query;
  }

  /**
   * Gets entities from the static cache.
   *
   * @param array $ids
   *   An array of entity IDs, or FALSE to load all entities.
   * @param array $conditions
   *   An array of conditions in the form 'field' => $value.
   *
   * @return array
   *   Array of entities from the entity cache.
   */
  protected function cacheGet($ids, $conditions = array()) {
    $organigrams_items = parent::cacheGet($ids, $conditions);

    // Name matching is case insensitive, note that with some collations
    // LOWER() and drupal_strtolower() may return different results.
    foreach ($organigrams_items as $organigrams_item) {

      // Convert organigrams item to an array.
      $organigrams_item_values = (array) $organigrams_item;

      // Remove any mismatching names.
      if (isset($conditions['name']) && drupal_strtolower($conditions['name'] != drupal_strtolower($organigrams_item_values['name']))) {

        // Remove the organigrams item.
        unset($organigrams_items[$organigrams_item->iid]);
      }
    }
    return $organigrams_items;
  }

}

/**
 * Implements hook_entity_presave().
 */
function organigrams_entity_presave($entity, $type) {
  switch ($type) {
    case 'organigrams_item':
      if (module_exists('rules')) {
        rules_invoke_event('organigrams_item_presave--' . $entity->organigrams_machine_name, $entity);
        rules_invoke_event('organigrams_item_presave', $entity);
      }
      break;
  }
}

/**
 * Implements hook_entity_update().
 */
function organigrams_entity_update($entity, $type) {
  switch ($type) {
    case 'organigrams_item':
      if (module_exists('rules')) {
        rules_invoke_event('organigrams_item_update--' . $entity->organigrams_machine_name, $entity);
        rules_invoke_event('organigrams_item_update', $entity);
      }
      break;
  }
}

/**
 * Implements hook_entity_insert().
 */
function organigrams_entity_insert($entity, $type) {
  switch ($type) {
    case 'organigrams_item':
      if (module_exists('rules')) {
        rules_invoke_event('organigrams_item_insert--' . $entity->organigrams_machine_name, $entity);
        rules_invoke_event('organigrams_item_insert', $entity);
      }
      break;
  }
}

/**
 * Implements hook_entity_delete().
 */
function organigrams_entity_delete($entity, $type) {
  switch ($type) {
    case 'organigrams_item':
      if (module_exists('rules')) {
        rules_invoke_event('organigrams_item_delete--' . $entity->organigrams_machine_name, $entity);
        rules_invoke_event('organigrams_item_delete', $entity);
      }
      break;
  }
}

Functions

Namesort descending Description
organigrams_block_info Implements hook_block_info().
organigrams_block_view Implements hook_block_view().
organigrams_check_machine_name Add an index to a machine name if it already exists to make sure its unique.
organigrams_compose_organigrams Generate an renderable item list array for the specified organigram.
organigrams_delete Delete an organigram given the organigrams ID.
organigrams_entity_access Access callback for the organigrams entities.
organigrams_entity_delete Implements hook_entity_delete().
organigrams_entity_info Implements hook_entity_info().
organigrams_entity_insert Implements hook_entity_insert().
organigrams_entity_presave Implements hook_entity_presave().
organigrams_entity_property_info Implements hook_entity_property_info().
organigrams_entity_update Implements hook_entity_update().
organigrams_entity_view Implements hook_entity_view().
organigrams_field_extra_fields Implements hook_field_extra_fields().
organigrams_generate_items_list Create a nested array with items to be used for generating an item list.
organigrams_get_item_by_name Try to map a string to an existing organigrams item, as for glossary use.
organigrams_get_names Get a list of organigram names.
organigrams_get_organigrams Get a list of organigrams objects.
organigrams_get_tree Create a hierarchical representation of an organigram.
organigrams_help Implements hook_help().
organigrams_import_items Import organigram items in an existing organigram.
organigrams_items_static_reset Clear all static cache variables for organigrams items.
organigrams_item_delete Delete an organigrams item.
organigrams_item_get_children Finds all children of an organigrams item ID.
organigrams_item_get_parent Find parent of a given organigrams item ID.
organigrams_item_get_suitable_parents_options Generate a list of suitable parents for the given organigrams item.
organigrams_item_load Get an organigrams item object matching the organigrams item ID.
organigrams_item_load_multiple Load multiple organigrams items based on certain conditions.
organigrams_item_save Save an organigrams item given an organigrams item object.
organigrams_item_title Get the organigrams item name which can be used as page title.
organigrams_libraries_info Implements hook_libraries_info().
organigrams_library Implements hook_library().
organigrams_load Get an organigrams object matching the organigrams ID.
organigrams_load_multiple Load multiple organigrams based on certain conditions.
organigrams_machine_name_load Get an organigrams object matching an organigrams machine name.
organigrams_menu Implements hook_menu().
organigrams_metadata_organigrams_item_setter Entity API property setter callback organigrams item.
organigrams_permission Implements hook_permission().
organigrams_rdf_mapping Implements hook_rdf_mapping().
organigrams_redirect_to_view_page Admin menu callback to redirect to the organigram view page.
organigrams_save Save an organigram given an organigrams object.
organigrams_theme Implements hook_theme().
organigrams_title Get the organigrams name which can be used as page title.
organigrams_tokens Implements hook_tokens().
organigrams_token_info Implements hook_token_info().
organigrams_user_access Get a value indicating whether the user perform the operation.
organigrams_view_page Menu callback to display an organigram.

Classes

Namesort descending Description
OrganigramsController Controller class for organigrams.
OrganigramsItemController Controller class for organigrams items.