You are here

media_browser_plus.folders.inc in Media Browser Plus 7.2

Folder manipulation functions

File

includes/media_browser_plus.folders.inc
View source
<?php

/**
 * @file
 * Folder manipulation functions
 */

/**
 * @todo Document what this function does.
 *
 * @param $form
 * @param $form_state
 */
function media_browser_plus_folder_list($form, &$form_state) {
  $destination = drupal_get_destination();
  $form['action-links'] = array(
    '#type' => 'markup',
    '#markup' => '<ul class="action-links"><li>' . l(t('Add new folder'), 'admin/content/file/add_folder', array(
      'query' => $destination,
    )) . '</li></ul>',
  );
  $header = array(
    'name' => array(
      'data' => t('Name'),
      'width' => '55%',
    ),
    'weight' => array(
      'data' => t('Weight'),
      'width' => '15%',
    ),
    'description' => array(
      'data' => t('Description'),
      'width' => '30%',
    ),
    'operations' => array(
      'data' => t('Operations'),
      'colspan' => 2,
    ),
  );
  drupal_add_tabledrag('folder-overview', 'match', 'parent', 'folder-pid', 'folder-pid', 'folder-folder_id', TRUE);
  drupal_add_tabledrag('folder-overview', 'order', 'sibling', 'folder-weight');

  // Get table rows.
  $rows = media_browser_plus_folder_admin_list();
  if (empty($rows)) {
    $rows[] = array(
      array(
        'data' => t('No folders created yet.'),
        'colspan' => '5',
      ),
    );
  }
  $output = theme('table', array(
    'header' => $header,
    'rows' => $rows,
    'attributes' => array(
      'id' => 'folder-overview',
    ),
  ));
  $form['admin'] = array(
    '#type' => 'markup',
    '#markup' => $output,
  );
  $form['actions'] = array(
    '#type' => 'actions',
  );
  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save Changes'),
  );
  $form['actions']['cancel'] = array(
    '#type' => 'submit',
    '#value' => t('Cancel'),
    '#submit' => array(
      'media_browser_plus_folder_admin_list_cancel',
    ),
  );
  return $form;
}

/**
 * @todo Document what this function is does.
 *
 * @param $form
 * @param $form_state
 */
function media_browser_plus_folder_list_submit($form, &$form_state) {
  foreach ($form_state['input'] as $key => $value) {
    if (strstr($key, 'folder_id')) {
      $folder = media_browser_plus_folder_load((int) $value['folder_id']);
      $source = media_browser_plus_construct_dir_path($folder);
      $folder->parent = (int) $value['pid'];
      $folder->weight = (int) $value['weight'];
      taxonomy_term_save($folder);
      $destination = media_browser_plus_construct_dir_path($folder);
      if ($source != $destination) {

        // Update physical folder structure.
        media_browser_plus_move_physical_folder($source, $destination);
      }
    }
  }
  drupal_set_message(t('Changes saved successfully'));
  $form_state['redirect'] = 'admin/content/file/thumbnails';
}

/**
 * @todo Document what this function is does.
 *
 * @param $form
 * @param $form_state
 */
function media_browser_plus_folder_admin_list_cancel($form, &$form_state) {
  $form_state['redirect'] = 'admin/content/file/thumbnails';
}

/**
 * @todo Document what this function does.
 *
 */
function media_browser_plus_folder_admin_list() {
  $vocabulary = taxonomy_vocabulary_machine_name_load('media_folders');
  $categories = array();
  $result = taxonomy_get_tree($vocabulary->vid);
  $destination = drupal_get_destination();
  $rows = array();
  foreach ($result as $key => $item) {
    $element['plid']['#attributes']['class'] = array(
      'menu-plid',
    );
    $element['mlid']['#attributes']['class'] = array(
      'menu-mlid',
    );
    $element['weight']['#attributes']['class'] = array(
      'menu-weight',
    );

    // Create row.
    $row = array();
    $row[] = theme('indentation', array(
      'size' => $item->depth,
    )) . $item->name;
    $row[] = media_browser_plus_folder_theme_folder_weight_column($item->weight, $item->tid, $item->parents[0]);
    $row[] = $item->description;
    $row[] = l(t('edit'), 'admin/content/file/folder/' . $item->tid . '/edit', array(
      'query' => $destination,
    ));
    $row[] = l(t('delete'), 'admin/content/file/folder/' . $item->tid . '/delete', array(
      'query' => $destination,
    ));

    // Change formate of row.
    $row = array(
      'data' => $row,
    );
    $row['class'][] = 'draggable';
    $rows[] = $row;
  }
  return $rows;
}

/**
 * @todo Document what this function is does.
 *
 * @param $form
 * @param $form_state
 */
function media_browser_plus_folder_add($form, &$form_state) {
  $form['new_folder'] = array(
    '#type' => 'fieldset',
    '#title' => t('New Folder'),
    'name' => array(
      '#type' => 'textfield',
      '#title' => t('Name'),
      '#description' => t('Please enter a folder name'),
      '#maxlength' => 125,
      '#required' => TRUE,
    ),
    'description' => array(
      '#type' => 'textfield',
      '#title' => t('Description'),
      '#description' => t('You may enter a brief description'),
      '#maxlength' => 255,
    ),
    'pid' => array(
      '#type' => 'select',
      '#title' => t('Parent Category'),
      '#options' => media_browser_plus_folder_get_folders(),
      '#description' => t('Sets one parent folder for the new folder'),
    ),
  );
  $form['actions'] = array(
    '#type' => 'actions',
    'submit' => array(
      '#type' => 'submit',
      '#value' => t('Save'),
      '#submit' => array(
        'media_browser_plus_folder_add_submit',
      ),
    ),
    'continue' => array(
      '#type' => 'submit',
      '#value' => t('Save & Continue'),
      '#submit' => array(
        'media_browser_plus_folder_add_submit_continue',
      ),
    ),
    'cancel' => array(
      '#type' => 'submit',
      '#value' => t('Cancel'),
      '#limit_validation_errors' => array(),
      '#submit' => array(
        'media_browser_plus_folder_add_cancel',
      ),
    ),
  );
  return $form;
}

/**
 * @todo Document what this function is does.
 *
 * @param $form
 * @param $form_state
 */
function media_browser_plus_folder_add_submit($form, &$form_state) {

  // Save folder.
  media_browser_plus_folder_save_folder($form_state);

  // Go back.
  $destination = drupal_get_destination();
  $form_state['redirect'] = $destination['destination'];
}

/**
 * @todo Document what this function is does.
 *
 * @param $form
 * @param $form_state
 */
function media_browser_plus_folder_add_submit_continue($form, &$form_state) {
  media_browser_plus_folder_save_folder($form_state);
  $destination = array();
  if (isset($_GET['destination'])) {
    $destination = drupal_get_destination();
    unset($_GET['destination']);
  }
  $form_state['redirect'] = array(
    'admin/content/file/add_folder',
    array(
      'query' => $destination,
    ),
  );
}

/**
 * @todo Document what this function is does.
 *
 * @param $form
 * @param $form_state
 * @param $folder
 */
function media_browser_plus_folder_edit($form, &$form_state, $folder) {
  $parents = taxonomy_get_parents($folder->tid);
  $parents_keys = array_keys($parents);
  $form['folder'] = array(
    '#type' => 'fieldset',
    '#title' => t('New Folder'),
    'folder_id' => array(
      '#type' => 'hidden',
      '#value' => $folder->tid,
    ),
    'name' => array(
      '#type' => 'textfield',
      '#title' => t('Name'),
      '#description' => t('Please enter a folder name'),
      '#maxlength' => 125,
      '#default_value' => $folder->name,
      '#required' => TRUE,
    ),
    'description' => array(
      '#type' => 'textfield',
      '#title' => t('Description'),
      '#description' => t('You may enter a brief description'),
      '#default_value' => $folder->description,
      '#maxlength' => 255,
    ),
    'pid' => array(
      '#type' => 'select',
      '#title' => t('Parent Category'),
      '#options' => media_browser_plus_folder_get_folders(),
      '#default_value' => count($parents) ? array_pop($parents_keys) : 0,
      '#description' => t('Sets one parent folder for the new folder'),
    ),
  );
  $form['actions'] = array(
    '#type' => 'actions',
    'submit' => array(
      '#type' => 'submit',
      '#value' => t('Save'),
      '#submit' => array(
        'media_browser_plus_folder_edit_submit',
      ),
    ),
    'delete' => array(
      '#type' => 'submit',
      '#value' => t('Delete'),
      '#submit' => array(
        'media_browser_plus_folder_edit_delete',
      ),
    ),
    'cancel' => array(
      '#type' => 'submit',
      '#value' => t('Cancel'),
      '#limit_validation_errors' => array(),
      '#submit' => array(
        'media_browser_plus_folder_add_cancel',
      ),
    ),
  );
  return $form;
}

/**
 * Validator for the settings form of the folder management.
 */
function media_browser_plus_folder_edit_validate($form, &$form_state) {
  if ($form_state['values']['pid'] == $form_state['values']['folder_id']) {
    form_set_error('pid', t('You cannot select a folder as parent of itself.'));
  }
}

/**
 * Submit handler for the settings form of the folder management.
 */
function media_browser_plus_folder_edit_submit($form, &$form_state) {

  // Save folder.
  media_browser_plus_folder_save_folder($form_state);

  // Go back.
  $destination = drupal_get_destination();
  $form_state['redirect'] = $destination['destination'];
}

/**
 * @todo Document what this function is does.
 *
 * @param $form
 * @param $form_state
 */
function media_browser_plus_folder_edit_delete($form, &$form_state) {
  if (isset($form_state['values']['folder_id'])) {
    $destination = array();
    if (isset($_GET['destination'])) {
      $destination = drupal_get_destination();
      unset($_GET['destination']);
    }
    $form_state['redirect'] = array(
      'admin/content/file/folder/' . (int) $form_state['values']['folder_id'] . '/delete',
      array(
        'query' => $destination,
      ),
    );
  }
}

/**
 * @todo Document what this function is does.
 *
 * @param $form
 * @param $form_state
 */
function media_browser_plus_folder_delete($form, &$form_state, $folder) {

  // Check if folder not empty and has no subfolders.
  $voc = taxonomy_vocabulary_machine_name_load('media_folders');
  $children = taxonomy_get_tree($voc->vid, $folder->tid);
  if (!_media_browser_plus_folder_empty($folder->tid) && count($children) == 0) {
    $form['intro'] = array(
      '#type' => 'item',
      '#markup' => t('Do you really want to delete the following folder:'),
    );
    $form['item'] = array(
      '#type' => 'item',
      '#markup' => $folder->name,
      '#prefix' => '<ul><li>',
      '#suffix' => '</ul></li>',
    );
    $form['note'] = array(
      '#type' => 'item',
      '#markup' => t('This action cannot be undone.'),
    );
    $form['folder_id'] = array(
      '#type' => 'hidden',
      '#value' => $folder->tid,
    );
    $form['actions'] = array(
      '#type' => 'actions',
      'delete' => array(
        '#type' => 'submit',
        '#value' => t('Delete'),
        '#submit' => array(
          'media_browser_plus_folder_delete_submit',
        ),
      ),
      'cancel' => array(
        '#type' => 'submit',
        '#value' => t('Cancel'),
        '#limit_validation_errors' => array(),
        '#submit' => array(
          'media_browser_plus_folder_add_cancel',
        ),
      ),
    );
    return $form;
  }
  else {
    if (count($children) != 0) {
      drupal_set_message(t('Folder %folder_name has subfolders and cannot be deleted', array(
        '%folder_name' => $folder->name,
      )), 'error');
    }
    if (_media_browser_plus_folder_empty($folder->tid)) {
      drupal_set_message(t('Folder %folder_name is not empty and cannot be deleted', array(
        '%folder_name' => $folder->name,
      )), 'error');
    }
    $destination = drupal_get_destination();
    drupal_goto($destination['destination']);
  }
}

/**
 * @todo Document what this function is does.
 *
 * @param $form
 * @param $form_state
 */
function media_browser_plus_folder_delete_submit($form, &$form_state) {

  // Load folder, delete and return.
  $folder = media_browser_plus_folder_load((int) $form_state['values']['folder_id']);
  $physical_folder = media_browser_plus_construct_dir_path($folder);
  if (taxonomy_term_delete($folder->tid)) {
    drupal_set_message(t('Folder %folder_name deleted successfully', array(
      '%folder_name' => $folder->name,
    )));
  }
  else {
    drupal_set_message(t('Error deleting folder %folder_name', array(
      '%folder_name' => $folder->name,
    )), 'error');
  }
  $destination = drupal_get_destination();
  $form_state['redirect'] = $destination['destination'];
}

/**
 * Submit handler of the mbp specific folder handling form.
 *
 * @see media_browser_plus_taxonomy_term_presave()
 * @see media_browser_plus_taxonomy_term_update()
 * @see media_browser_plus_taxonomy_term_insert()
 */
function media_browser_plus_folder_save_folder($form_state) {
  $vocabulary = taxonomy_vocabulary_machine_name_load('media_folders');
  $term = new stdClass();
  if (isset($form_state['values']['folder_id'])) {
    $term->tid = (int) $form_state['values']['folder_id'];
    $source = media_browser_plus_construct_dir_path($term);
  }
  $term->name = check_plain($form_state['values']['name']);
  $term->description = check_plain($form_state['values']['description']);
  $term->parent = (int) $form_state['values']['pid'];
  $term->vid = $vocabulary->vid;

  // Save (folder) term. Further processing is done in the taxonomy term related
  // hooks.
  taxonomy_term_save($term);
}

/**
 * Moves the root folder of media files.
 *
 * Updates the variable media_root_folder too.
 *
 * @param string $source
 *   Source path.
 * @param string $destination
 *   Destination path.
 */
function media_browser_plus_move_root_folder($source, $destination) {
  if (!empty($source)) {
    $source .= '/';
  }
  if (!empty($destination)) {
    $destination .= '/';
  }
  $scheme = variable_get('file_default_scheme', 'public') . '://';
  $source = $scheme . $source;
  $destination = $scheme . $destination;
  file_prepare_directory($destination, FILE_CREATE_DIRECTORY);

  // Load root folder term.
  $root_folder_term = media_browser_plus_get_media_root_folder();

  // Move media files in root folder itself. We do this because if the root
  // folder was located in the default file directory of Drupal we can't move
  // all files / folders.
  $conditions = array();
  $conditions[] = array(
    'field' => array(
      'field_folder',
      'tid',
      $root_folder_term->tid,
      '=',
    ),
  );
  $options = array(
    'apply_filter' => FALSE,
    'paging' => FALSE,
    'conditions' => $conditions,
  );
  $file_entities = media_browser_plus_load_multiple($options);
  if (!empty($file_entities->results)) {
    foreach ($file_entities->results as $file_entity) {
      file_move($file_entity, $destination);
    }
  }

  // Move subfolders.
  $root_subfolders = taxonomy_get_children($root_folder_term->tid);
  foreach ($root_subfolders as $subfolder) {
    $subfolder_source = media_browser_plus_construct_dir_path($subfolder);
    $subfolder_destination = str_replace($source, $destination, $subfolder_source);
    media_browser_plus_move_subfolder($subfolder, $subfolder_source, $subfolder_destination);
  }
  variable_set('media_root_folder', trim($destination, '/'));
}

/**
 * Helper function to move a subfolder - and update the related files.
 *
 * @param object $folder
 *   The _updated_ folder term. Is used to generate the destination.
 * @param string $source
 *   The path of the old/current location.
 * @param string $destination
 *   The path of the new location.
 *
 * @return boolean
 *   Returns FALSE if the processing failed e.g. if the source and destination
 *   are the same location.
 */
function media_browser_plus_move_subfolder($folder, $source, $destination) {
  if ($source != $destination) {

    // This will move all subfolders too. Thus we have to handle all child
    // folder terms as well.
    media_browser_plus_move_physical_folder($source, $destination);

    // Update files in folder and subfolders get folders.
    $folders = array(
      $folder->tid,
    );

    // Fetch all sub-folders.
    $sub_folders = taxonomy_get_tree($folder->vid, $folder->tid);
    foreach ($sub_folders as $sub_folder) {
      $folders[] = $sub_folder->tid;
    }

    // Set batch.
    $batch = array(
      'title' => t('Updating Media'),
      'operations' => array(
        array(
          'media_browser_plus_folder_update_file_locations_batch',
          array(
            $folders,
          ),
        ),
      ),
      'finished' => 'media_browser_plus_folder_update_file_locations_batch_complete',
      'file' => drupal_get_path('module', 'media_browser_plus') . '/includes/media_browser_plus.folders.inc',
    );
    batch_set($batch);
    return TRUE;
  }
  return FALSE;
}

/**
 * @todo Document what this function is does.
 */
function media_browser_plus_folder_get_folders() {
  $vocabulary = taxonomy_vocabulary_machine_name_load('media_folders');
  $folders = array(
    0 => '> ' . t('No Parent') . ' <',
  );
  foreach (taxonomy_get_tree($vocabulary->vid) as $key => $value) {
    $folders[$value->tid] = str_pad('', $value->depth, '-') . $value->name;
  }
  return $folders;
}

/**
 * Simple form cancel redirect.
 *
 * @param $form
 * @param $form_state
 */
function media_browser_plus_folder_add_cancel($form, &$form_state) {
  $destination = drupal_get_destination();
  $form_state['redirect'] = $destination['destination'];
}

/**
 * @todo Document what this function does.
 *
 * @param $weight
 * @param $folder_id
 * @param $pid
 */
function media_browser_plus_folder_theme_folder_weight_column($weight, $folder_id, $pid) {

  // Create the necessary div & select form.
  $output = '<div class="form-item form-type-select form-item-folder_id:' . $folder_id . '-weight">
    <select name="folder_id:' . $folder_id . '[weight]" class="folder-weight form-select" id="edit-folder_id' . $folder_id . '-weight" >';
  $options = range(-50, 50);
  foreach ($options as $option) {
    $output .= '<option ' . ($option == $weight ? 'selected="selected"' : '') . ' value="' . $option . '">' . $option . '</option>';
  }
  $output .= '</select></div>';
  $output .= '<input type="hidden" id="edit-folder_id' . $folder_id . '-pid" class="folder-pid" value="' . $pid . '" name="folder_id:' . $folder_id . '[pid]" />';
  $output .= '<input type="hidden" id="edit-folder_id' . $folder_id . '-folder_id" class="folder-folder_id" value="' . $folder_id . '" name="folder_id:' . $folder_id . '[folder_id]" />';
  return $output;
}

/**
 * Batch function that updates all media URIs inside the given folders.
 *
 * @param $folders
 * @param $context
 */
function media_browser_plus_folder_update_file_locations_batch($folders, &$context) {
  $per_page = 25;
  $conditions = array();
  $conditions[] = array(
    'field' => array(
      'field_folder',
      'tid',
      $folders,
      'IN',
    ),
  );
  $options = array(
    'apply_filter' => FALSE,
    'count_only' => TRUE,
    'conditions' => $conditions,
  );
  $media_count = media_browser_plus_load_multiple($options);
  if (empty($context['sandbox'])) {
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['max'] = $media_count;
  }

  // Look how far we got and where we have to resume.
  $media_start = $context['sandbox']['progress'];
  $page = $media_start == 0 ? 0 : round($media_start / $per_page, 0);
  if (!isset($context['results'])) {
    $context['results'] = array(
      'success' => array(),
      'errors' => array(),
    );
  }
  $attributes = array(
    'apply_filter' => FALSE,
    'paging' => TRUE,
    'per_page' => $per_page,
    'page' => $page,
    'conditions' => $conditions,
  );
  $media_query = media_browser_plus_load_multiple($attributes);

  // Checking media.
  foreach ($media_query->results as $media) {
    if (isset($media->field_folder[LANGUAGE_NONE][0]['tid'])) {
      $source = clone $media;
      $path = media_browser_plus_construct_dir_path(taxonomy_term_load($media->field_folder[LANGUAGE_NONE][0]['tid']));
      $media->uri = $path . '/' . basename($media->uri);
      file_save($media);

      // Inform modules that the file has been moved.
      module_invoke_all('file_move', $media, $source);
    }
  }

  // Increment start.
  $media_start = $media_start + $per_page;

  // Make sure start is not above max (for progress).
  $media_start = $media_start > $media_count ? $media_count : $media_start;

  // Set sandbox value.
  $context['sandbox']['max'] = $media_count;
  $context['sandbox']['progress'] = $media_start;

  // Set other context values.
  $context['message'] = t('Updating') . '...(' . $context['sandbox']['progress'] . '/' . $context['sandbox']['max'] . ') ';
  if ($context['sandbox']['progress'] < $context['sandbox']['max']) {
    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
  }
}

/**
 * Called on completion of the batch.
 *
 * @param type $success
 * @param type $results
 * @param type $operations
 */
function media_browser_plus_folder_update_file_locations_batch_complete($success, $results, $operations) {
  if ($success) {
    drupal_set_message(t('Successfully updated all URIs'));
  }
  else {
    drupal_set_message(t('Error during media batch'), 'error');
  }
}

Functions

Namesort descending Description
media_browser_plus_folder_add @todo Document what this function is does.
media_browser_plus_folder_add_cancel Simple form cancel redirect.
media_browser_plus_folder_add_submit @todo Document what this function is does.
media_browser_plus_folder_add_submit_continue @todo Document what this function is does.
media_browser_plus_folder_admin_list @todo Document what this function does.
media_browser_plus_folder_admin_list_cancel @todo Document what this function is does.
media_browser_plus_folder_delete @todo Document what this function is does.
media_browser_plus_folder_delete_submit @todo Document what this function is does.
media_browser_plus_folder_edit @todo Document what this function is does.
media_browser_plus_folder_edit_delete @todo Document what this function is does.
media_browser_plus_folder_edit_submit Submit handler for the settings form of the folder management.
media_browser_plus_folder_edit_validate Validator for the settings form of the folder management.
media_browser_plus_folder_get_folders @todo Document what this function is does.
media_browser_plus_folder_list @todo Document what this function does.
media_browser_plus_folder_list_submit @todo Document what this function is does.
media_browser_plus_folder_save_folder Submit handler of the mbp specific folder handling form.
media_browser_plus_folder_theme_folder_weight_column @todo Document what this function does.
media_browser_plus_folder_update_file_locations_batch Batch function that updates all media URIs inside the given folders.
media_browser_plus_folder_update_file_locations_batch_complete Called on completion of the batch.
media_browser_plus_move_root_folder Moves the root folder of media files.
media_browser_plus_move_subfolder Helper function to move a subfolder - and update the related files.