123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466 |
- <?php
- /**
- * @file
- * Contains core functions for the FileField Paths module.
- */
- /**
- * Include additional files.
- */
- foreach (module_list() as $module) {
- if (file_exists($file = dirname(__FILE__) . "/modules/{$module}.inc")) {
- require_once $file;
- }
- }
- /**
- * Implements hook_form_alter().
- */
- function filefield_paths_form_alter(&$form, $form_state, $form_id) {
- $ffp = array();
- // Invoke hook_filefield_paths_form_alter().
- foreach (module_implements('filefield_paths_form_alter') as $module) {
- $function = "{$module}_filefield_paths_form_alter";
- $function($form, $ffp);
- }
- // If supporting module enabled, show FileField Paths settings form.
- if (count($ffp) > 0) {
- $entity_info = entity_get_info($form['#instance']['entity_type']);
- $fields = module_invoke_all('filefield_paths_field_settings');
- foreach ($ffp as $field_name => $field_data) {
- $active_updating = 0;
- $results = db_select('filefield_paths', 'f')
- ->fields('f')
- ->condition('type', $field_data['type'])
- ->condition('field', $field_name)
- ->execute()
- ->fetchAllAssoc('type');
- if (!empty($results[$field_data['type']])) {
- $result = $results[$field_data['type']];
- foreach ($fields as &$field) {
- $field['settings'] = unserialize($result->{$field['sql']});
- }
- unset($field);
- $active_updating = $result->active_updating;
- }
- $count = 0;
- foreach ($fields as $name => $field) {
- $count++;
- if (isset($field['form']) && is_array($field['form'])) {
- $keys = array_keys($field['form']);
- for ($i = 1; $i < count($field['form']); $i++) {
- $field['form'][$keys[$i]]['#weight'] = ($count - 1) * 3 + 2 + $i;
- $field['form'][$keys[$i]]['#element_validate'] = array('token_element_validate');
- $field['form'][$keys[$i]]['#token_types'] = array('file', $entity_info['token type']);
- }
- unset($keys);
- $field_data['form_path'] = array_merge_recursive($field_data['form_path'], $field['form']);
- }
- $field_data['form_path']['#tree'] = TRUE;
- $field_data['form_path'][$name]['#weight'] = ($count - 1) * 3;
- // Set defualt value for patterns.
- if (isset($field['settings']['value'])) {
- $field_data['form_path'][$name]['#default_value'] = $field['settings']['value'];
- if (isset($field['data'])) {
- foreach ($field['data'] as $key => $value) {
- $field_data['form_path'][$value]['#default_value'] = $field['settings'][$key];
- }
- }
- }
- $field_data['form_path']["{$name}_cleanup"] = array(
- '#type' => 'fieldset',
- '#title' => t('@title cleanup settings', array('@title' => $field['title'])),
- '#collapsible' => TRUE,
- '#collapsed' => TRUE,
- '#weight' => ($count - 1) * 3 + 1,
- '#attributes' => array(
- 'class' => array("{$name} cleanup")
- )
- );
- // Cleanup field with Pathauto module.
- $field_data['form_path']["{$name}_cleanup"]["{$name}_pathauto"] = array(
- '#type' => 'checkbox',
- '#title' => t('Cleanup using Pathauto') . '.',
- '#default_value' => isset($field['settings']['pathauto'])
- ? $field['settings']['pathauto']
- : 0
- ,
- '#description' => t('Cleanup @title using', array('@title' => $field['title'])) . ' ' . l(t('Pathauto settings'), 'admin/config/search/path/settings'),
- );
- if (!module_exists('pathauto')) {
- $field_data['form_path']["{$name}_cleanup"]["{$name}_pathauto"]['#disabled'] = TRUE;
- $field_data['form_path']["{$name}_cleanup"]["{$name}_pathauto"]['#default_value'] = 0;
- }
- // Convert field to lower case.
- $field_data['form_path']["{$name}_cleanup"]["{$name}_tolower"] = array(
- '#type' => 'checkbox',
- '#title' => t('Convert to lower case') . '.',
- '#default_value' => isset($field['settings']['tolower'])
- ? $field['settings']['tolower']
- : 0
- ,
- '#description' => t('Convert @title to lower case', array('@title' => $field['title'])) . '.'
- );
- // Transliterate field with Transliteration module.
- $field_data['form_path']["{$name}_cleanup"]["{$name}_transliterate"] = array(
- '#type' => 'checkbox',
- '#title' => t('Transliterate') . '.',
- '#default_value' => isset($field['settings']['transliterate'])
- ? $field['settings']['transliterate']
- : 0
- ,
- '#description' => t('Transliterate @title', array('@title' => $field['title'])) . '.'
- );
- if (!module_exists('transliteration')) {
- $field_data['form_path']["{$name}_cleanup"]["{$name}_transliterate"]['#disabled'] = TRUE;
- $field_data['form_path']["{$name}_cleanup"]["{$name}_transliterate"]['#default_value'] = 0;
- }
- }
- // Replacement patterns for field.
- $field_data['form_path']['token_tree'] = array(
- '#type' => 'fieldset',
- '#title' => t('Replacement patterns'),
- '#collapsible' => TRUE,
- '#collapsed' => TRUE,
- '#description' => theme('token_tree', array('token_types' => array('file', $entity_info['token type']))),
- '#weight' => 10,
- );
- // Retroactive updates.
- $field_data['form_path']['retroactive_update'] = array(
- '#type' => 'checkbox',
- '#title' => t('Retroactive update'),
- '#description' => t('Move and rename previously uploaded files') . '.' .
- '<br /> <strong style="color: #FF0000;">' . t('Warning') . ':</strong> ' .
- t('This feature should only be used on developmental servers or with extreme caution') . '.',
- '#weight' => 11
- );
- // Active updating.
- $field_data['form_path']['active_updating'] = array(
- '#type' => 'checkbox',
- '#title' => t('Active updating'),
- '#default_value' => $active_updating,
- '#description' => t('Actively move and rename previously uploaded files as required') . '.' .
- '<br /> <strong style="color: #FF0000;">' . t('Warning') . ':</strong> ' .
- t('This feature should only be used on developmental servers or with extreme caution') . '.',
- '#weight' => 12
- );
- if (!in_array('filefield_paths_form_submit', $form['#submit'])) {
- $form['#submit'][] = 'filefield_paths_form_submit';
- }
- }
- }
- }
- /**
- * Implements hook_form_submit().
- */
- function filefield_paths_form_submit($form, &$form_state) {
- $ffp = array();
- // Invoke hook_filefield_paths_form_submit().
- foreach (module_implements('filefield_paths_form_submit') as $module) {
- $function = "{$module}_filefield_paths_form_submit";
- $function($form_state, $ffp);
- }
- if (count($ffp) > 0) {
- $retroactive_update = FALSE;
- $fields = module_invoke_all('filefield_paths_field_settings');
- foreach ($ffp as $field_name => $field_data) {
- $cols = array(
- 'type' => $field_data['type'],
- 'field' => $field_name,
- 'active_updating' => $form_state['values']["ffp_{$field_name}"]['active_updating'],
- );
- foreach ($fields as $name => &$field) {
- $cols[$field['sql']] = array(
- 'value' => $form_state['values']["ffp_{$field_name}"][$name],
- 'tolower' => $form_state['values']["ffp_{$field_name}"]["{$name}_cleanup"]["{$name}_tolower"],
- 'pathauto' => $form_state['values']["ffp_{$field_name}"]["{$name}_cleanup"]["{$name}_pathauto"],
- 'transliterate' => $form_state['values']["ffp_{$field_name}"]["{$name}_cleanup"]["{$name}_transliterate"],
- );
- // Store additional settings from add-on modules.
- if (isset($field['data'])) {
- foreach ($field['data'] as $key => $value) {
- $cols[$field['sql']][$key] = $form_state['values']["ffp_{$field_name}"][$value];
- }
- }
- }
- $results = db_select('filefield_paths', 'f')
- ->fields('f')
- ->condition('type', $cols['type'])
- ->condition('field', $cols['field'])
- ->execute()
- ->fetchAll();
- // Update existing entry.
- if (!empty($results)) {
- drupal_write_record('filefield_paths', $cols, array('type', 'field'));
- }
- // Create new entry.
- else {
- drupal_write_record('filefield_paths', $cols);
- }
- if ($form_state['values']["ffp_{$field_name}"]['retroactive_update']) {
- $retroactive_update = TRUE;
- $module = isset($form['#field']) ? $form['#field']['module'] : $field_name;
- filefield_paths_batch_update($form_state['values']['instance']);
- }
- }
- if ($retroactive_update) {
- // Run batch.
- batch_process($form_state['redirect']);
- }
- }
- }
- /**
- * Set batch process to update FileField Paths.
- *
- * @param $instance
- */
- function filefield_paths_batch_update($instance) {
- $objects = array();
- // Invoke hook_filefield_paths_batch_update().
- if (function_exists($function = "{$instance['widget']['module']}_filefield_paths_batch_update")) {
- $function($instance, $objects);
- }
- // Create batch.
- $batch = array(
- 'title' => t('Updating FileField Paths'),
- 'operations' => array(
- array('_filefield_paths_batch_update_process', array($objects, $instance))
- ),
- );
- batch_set($batch);
- }
- function _filefield_paths_batch_update_process($objects, $instance, &$context) {
- if (!isset($context['sandbox']['progress'])) {
- $context['sandbox']['progress'] = 0;
- $context['sandbox']['max'] = count($objects);
- $context['sandbox']['objects'] = $objects;
- }
- // Process nodes by groups of 5.
- $count = min(5, count($context['sandbox']['objects']));
- for ($i = 1; $i <= $count; $i++) {
- // For each oid, load the object, update the files and save it.
- $oid = array_shift($context['sandbox']['objects']);
- // Invoke hook_filefield_paths_update().
- if (function_exists($function = "{$instance['widget']['module']}_filefield_paths_update")) {
- $function($oid, $instance);
- }
- // Update our progress information.
- $context['sandbox']['progress']++;
- }
- // Inform the batch engine that we are not finished,
- // and provide an estimation of the completion level we reached.
- if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
- $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
- }
- }
- /**
- * Implements hook_entity_insert().
- */
- function filefield_paths_entity_insert($entity, $type) {
- filefield_paths_entity_update($entity, $type);
- }
- /**
- * Implements hook_entity_update().
- */
- function filefield_paths_entity_update($entity, $type) {
- if (($ffp = filefield_paths_get_fields($entity, $type)) !== FALSE) {
- $update = new stdClass;
- $update->entity = FALSE;
- // Process files.
- foreach ($ffp['#files'] as &$file) {
- // Invoke hook_filefield_paths_process_file().
- foreach (module_implements('filefield_paths_process_file') as $module) {
- $function = "{$module}_filefield_paths_process_file";
- $settings = isset($ffp['#settings'][$file['name']]) ? $ffp['#settings'][$file['name']] : NULL;
- if (!is_null($settings)) {
- $function(($file['new'] || $settings['active_updating']), $file, $settings, $entity, $type, $update);
- }
- }
- }
- if ($update->entity == TRUE) {
- field_attach_update($type, $entity);
- }
- // Cleanup temporary paths.
- if ($ffp['#settings']) {
- foreach ($ffp['#settings'] as $name => $field) {
- // Invoke hook_filefield_paths_cleanup().
- foreach (module_implements('filefield_paths_cleanup') as $module) {
- $function = "{$module}_filefield_paths_cleanup";
- $function($ffp, $name);
- }
- }
- }
- }
- }
- /**
- * Implements hook_file_presave().
- */
- function filefield_paths_file_presave($file) {
- // Store original filename in the database.
- if (empty($file->origname)) {
- $file->origname = $file->filename;
- }
- }
- /**
- * Implements hook_field_delete_instance().
- */
- function filefield_paths_field_delete_instance($instance) {
- db_delete('filefield_paths')
- ->condition('type', "{$instance['entity_type']}::{$instance['bundle']}")
- ->condition('field', $instance['field_name'])
- ->execute();
- }
- /**
- *
- */
- function filefield_paths_get_fields(&$entity, $type, $op = NULL) {
- $ffp = array();
- $entity_info = entity_get_info();
- // Invoke hook_filefield_paths_get_fields().
- foreach (module_implements('filefield_paths_get_fields') as $module) {
- $function = "{$module}_filefield_paths_get_fields";
- $function($entity, $ffp);
- }
- if (count($ffp) == 0 || (isset($ffp['#types']) && !is_array($ffp['#types']))) {
- return FALSE;
- }
- $fields = module_invoke_all('filefield_paths_field_settings');
- // Load fields settings
- foreach (array_keys($ffp['#types']) as $name) {
- $field_type = isset($entity->{$entity_info[$type]['entity keys']['bundle']}) ? "{$type}::{$entity->{$entity_info[$type]['entity keys']['bundle']}}" : "{$type}::{$type}";
- $results = db_select('filefield_paths', 'f')
- ->fields('f')
- ->condition('type', $field_type)
- ->condition('field', $name)
- ->execute()
- ->fetchAllAssoc('type');
- if (!empty($results[$field_type])) {
- $result = $results[$field_type];
- foreach ($fields as $field) {
- $ffp['#settings'][$name][$field['sql']] = unserialize($result->$field['sql']);
- }
- $ffp['#settings'][$name]['active_updating'] = $result->active_updating;
- }
- }
- return $ffp;
- }
- /**
- * Run regular expression over all available text-based fields.
- */
- function _filefield_paths_replace_path($old, $new, &$entity, &$update) {
- // Build regular expression.
- $info = parse_url($old);
- $info['path'] = !empty($info['path']) ? $info['path'] : '';
- $absolute = str_replace("{$info['host']}{$info['path']}", '', file_create_url($old));
- $relative = parse_url($absolute, PHP_URL_PATH);
- $regex = str_replace('/', '\/', "({$absolute}|{$relative}|{$info['scheme']}://)(styles/.*?/{$info['scheme']}/|)({$info['host']}{$info['path']})");
- // Build replacement.
- $info = parse_url($new);
- $replacement = "\$1\$2{$info['host']}{$info['path']}";
- $fields = field_info_fields();
- foreach ($fields as $name => $field) {
- if ($field['module'] == 'text' && isset($entity->{$field['field_name']}) && is_array($entity->{$field['field_name']})) {
- foreach ($entity->{$field['field_name']} as &$language) {
- foreach ($language as &$item) {
- $item['value'] = preg_replace("/$regex/", $replacement, $item['value']);
- }
- }
- }
- }
- }
- /**
- * Process and cleanup strings.
- */
- function filefield_paths_process_string($value, $data, $settings = array()) {
- $transliterate = module_exists('transliteration') && isset($settings['transliterate']) && $settings['transliterate'];
- $pathauto = module_exists('pathauto') && isset($settings['pathauto']) && $settings['pathauto'] == TRUE;
- if ($pathauto == TRUE) {
- module_load_include('inc', 'pathauto');
- }
- $paths = explode('/', $value);
- foreach ($paths as &$path) {
- // Process string tokens.
- $path = token_replace($path, $data, array('clear' => TRUE));
- // Cleanup with pathauto.
- if ($pathauto == TRUE) {
- $path_parts = explode('.', $path);
- foreach ($path_parts as &$path_part) {
- $path_part = pathauto_cleanstring($path_part);
- }
- $path = implode('.', $path_parts);
- }
- // Transliterate string.
- if ($transliterate == TRUE) {
- $path = transliteration_clean_filename($path);
- }
- }
- $value = implode('/', $paths);
- // Convert string to lower case.
- if (isset($settings['tolower']) && $settings['tolower'] == TRUE) {
- $value = drupal_strtolower($value);
- }
- // Ensure that there are no double-slash sequences due to empty token values.
- $value = preg_replace('/\/+/', '/', $value);
- return $value;
- }
|