You are here

asset.module in Asset 5

Same filename and directory in other branches
  1. 5.2 asset.module
  2. 6 asset.module
  3. 7 asset.module

File

asset.module
View source
<?php

define('ASSET_PRIVATE', 0);
define('ASSET_PUBLIC', 1);
function _asset_include() {

  // get the path once
  $path = drupal_get_path('module', 'asset');

  // load the views hooks if the views module is enabled
  if (module_exists('views')) {
    require_once $path . '/asset_views.inc';
  }

  // Load all our module 'on behalfs'.
  $files = drupal_system_listing('asset_.*\\.inc$', $path . '/modules', 'name', 0);
  foreach ($files as $file) {

    // The filename format is very specific. It must be asset_MODULENAME.inc
    $module = substr_replace($file->name, '', 0, 6);
    if (module_exists($module)) {
      require_once "./{$file->filename}";
    }
  }
}
_asset_include();

/**
 * Implementation of hook_menu()
 */
function asset_menu($may_cache) {
  if ($may_cache) {
    $items[] = array(
      'path' => 'asset/widget/js',
      'callback' => 'asset_widget_js',
      'access' => user_access('access content'),
      'type' => MENU_CALLBACK,
    );
    $items[] = array(
      'type' => MENU_CALLBACK,
      'title' => t('Asset Wizard'),
      'path' => 'asset/wizard',
      'callback' => 'asset_wizard',
      'access' => user_access('create assets') || user_access('administer assets'),
    );
    $items[] = array(
      'type' => MENU_CALLBACK,
      'path' => 'asset/js/preview',
      'callback' => 'asset_js_preview',
      'access' => user_access('create assets') || user_access('administer assets'),
    );
    $items[] = array(
      'path' => 'admin/settings/asset',
      'title' => t('Asset'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'asset_admin_settings',
      ),
      'access' => user_access('administer assets'),
    );
    $items[] = array(
      'path' => 'admin/settings/asset/settings',
      'title' => t('Settings'),
      'access' => user_access('administer assets'),
      'type' => MENU_DEFAULT_LOCAL_TASK,
      'weight' => -1,
    );
    $items[] = array(
      'path' => 'admin/settings/asset/defaults',
      'title' => t('Formatter Defaults'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'asset_admin_formatter_defaults',
      ),
      'access' => user_access('administer assets'),
      'type' => MENU_LOCAL_TASK,
    );
    foreach (module_implements('asset_settings') as $module) {
      $items[] = array(
        'path' => 'admin/settings/asset/' . $module,
        'title' => $module,
        'callback' => 'drupal_get_form',
        'callback arguments' => array(
          $module . '_asset_settings',
        ),
        'access' => user_access('administer assets'),
        'type' => MENU_LOCAL_TASK,
        'weight' => 5,
      );
    }
    $items[] = array(
      'path' => 'asset/img',
      'type' => MENU_CALLBACK,
      'callback' => 'asset_img_preview',
      'access' => user_access('create assets'),
    );
  }
  else {
    module_invoke_all('asset_formatter', 'init');
    drupal_add_css(drupal_get_path('module', 'asset') . '/asset.css');
  }
  return $items;
}

/**
 * Implementation of hook_perm().
 */
function asset_perm() {
  $perms = array(
    'create assets',
    'administer assets',
  );
  foreach (module_implements('asset_type') as $module) {
    $types = module_invoke($module, 'asset_type', 'info');
    foreach ($types as $delta => $type) {
      $perms[] = 'create ' . $delta . ' assets';
    }
  }
  return $perms;
}

/**
 * Persist an asset object to the db
 * 
 * @param $asset
 *   asset object with filename, filepath, filemime, and filesize properties
 * @param $form_values
 *   form_values array from asset creation form. this allows asset_save to set
 *   the defaults for fields like title, author and permissions.
 */
function asset_save($asset, $form_values = array()) {
  $path = file_directory_path();
  if (substr($asset->filepath, 0, strlen($path)) == $path) {
    $asset->filepath = trim(substr($asset->filepath, strlen($path)), '/');
  }
  $info = pathinfo($asset->filepath);
  if ($info['dirname'] == '.') {
    $info['dirname'] = '';
  }
  if ($asset->type == "directory") {
    $info['dirname'] = $form_values['parent'];
    $info['basename'] = $form_values['title'];
  }
  $default_fields = array(
    'title',
    'author',
    'description',
    'roles',
    'status',
  );
  foreach ($default_fields as $field) {
    $asset->{$field} = $form_values[$field];
  }
  $asset->uid = $asset->uid ? $asset->uid : $GLOBALS['user']->uid;
  $asset->status = $asset->status ? ASSET_PUBLIC : ASSET_PRIVATE;
  $asset->type = $asset->type ? $asset->type : 'local';

  // make sure to set aid on the asset object, so modules can use it in assetapi insert
  $asset->aid = db_next_id('{asset}_aid');
  db_query("INSERT INTO {asset} (aid,type,dirname,filename,extension,filesize,uid,status,title,author,description) VALUES (%d, '%s', '%s', '%s', '%s', %d, %d, %d, '%s', '%s', '%s')", $asset->aid, $asset->type, $info['dirname'], $info['basename'], $info['extension'], $asset->filesize, $asset->uid, $asset->status, $asset->title, $asset->author, $asset->description);
  if ($asset->status == ASSET_PRIVATE && is_array($asset->roles)) {
    foreach ($asset->roles as $rid => $status) {
      db_query('INSERT INTO {asset_role} (aid, rid, status) VALUES (%d, %d, %d)', array(
        $asset->aid,
        $rid,
        $status ? ASSET_PUBLIC : ASSET_PRIVATE,
      ));
    }
  }
  module_invoke_all('assetapi', 'insert', $asset);
  return asset_load($asset->aid);
}

/**
 * Load an asset object from db and set some default properties. 
 * Taken almost exactly from node_load to utilize caching and assetapi load hook
 * 
 * @param $aid
 *    id of asset to load
 */
function asset_load($param = array(), $reset = NULL) {
  static $assets = array();
  if ($reset) {
    $assets = array();
  }
  $arguments = array();
  if (is_numeric($param)) {
    if (isset($assets[$param])) {
      return is_object($assets[$param]) ? drupal_clone($assets[$param]) : $assets[$param];
    }
    $cond = 'a.aid = %d';
    $arguments[] = $param;
  }
  elseif (is_array($param)) {

    // Turn the conditions into a query.
    foreach ($param as $key => $value) {
      $cond[] = 'a.' . db_escape_string($key) . " = '%s'";
      $arguments[] = $value;
    }
    $cond = implode(' AND ', $cond);
  }
  else {
    return false;
  }

  // Retrieve the asset.
  $asset = db_fetch_object(db_query('SELECT a.* FROM {asset} a WHERE ' . $cond, $arguments));
  if (!$asset) {
    return false;
  }
  $dirname_tmp = $asset->dirname ? $asset->dirname . '/' : $asset->dirname;
  $result = db_query('SELECT * FROM {asset_role} WHERE aid=%d', $asset->aid);
  while ($role = db_fetch_array($result)) {
    $asset->roles[$role['rid']] = $role['status'] ? $role['rid'] : 0;
  }
  $asset->filepath = file_create_path($dirname_tmp . $asset->filename);
  $asset->url = file_create_url($dirname_tmp . $asset->filename);
  $asset->extension = strtolower($asset->extension);
  $asset->title = $asset->title ? $asset->title : $asset->filename;
  if ($asset->type == 'directory' && $asset->dirname == '' && $asset->filename == $GLOBALS['user']->name) {
    $asset->title = t('My Assets');
  }
  if ($asset->aid) {
    if ($extra = module_invoke_all('assetapi', 'load', $asset)) {
      foreach ($extra as $key => $value) {
        $asset->{$key} = $value;
      }
    }
    $assets[$asset->aid] = is_object($asset) ? drupal_clone($asset) : $asset;
  }
  return $asset;
}

/**
 * Admin Settings
 */
function asset_admin_settings() {
  $form['asset_access_option'] = array(
    '#type' => 'radios',
    '#title' => t('Visibility Options'),
    '#default_value' => variable_get('asset_access_option', 1),
    '#options' => array(
      t('Show on every page except the listed pages.'),
      t('Show on only the listed pages.'),
      t('Show if the following PHP code returns <code>TRUE</code> (PHP-mode, experts only).'),
    ),
  );
  $form['asset_access_pages'] = array(
    '#type' => 'textarea',
    '#title' => t('Pages'),
    '#default_value' => variable_get('asset_access_pages', "node/add/*\nnode/*/edit"),
    '#description' => t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are 'blog' for the blog page and blog/* for every personal blog. <front> is the front page.If the PHP-mode is chosen, enter PHP code between <?php ?>. Note that executing incorrect PHP-code can break your Drupal site. Also note that if you are using a WYSIWYG editor, the asset button may be available in that editor regardless of this setting."),
  );
  $form['asset_wizard_theme'] = array(
    '#type' => 'fieldset',
    '#title' => t('Wizard theme'),
    '#theme' => 'asset_wizard_theme_form',
  );
  $paths = array(
    drupal_get_path('module', 'asset') . '/themes',
    drupal_get_path('theme', variable_get('theme_default', 'garland')),
  );
  foreach ($paths as $path) {
    $files = file_scan_directory($path, 'asset_wizard\\.css$');
    foreach ($files as $filename => $file) {
      $form['asset_wizard_theme'][$filename] = array(
        '#type' => 'radio',
        '#return_value' => $filename,
        '#default_value' => variable_get('asset_wizard_theme', drupal_get_path('module', 'asset') . '/themes/default/asset_wizard.css'),
        '#parents' => array(
          'asset_wizard_theme',
        ),
      );
    }
  }
  return system_settings_form($form);
}

/**
 * Menu callback for selection of default formatting options.
 */
function asset_admin_formatter_defaults() {
  $form = array();
  $formatters = asset_get_formatters(true);
  foreach ($formatters as $type => $exts) {
    $form[$type] = array(
      '#type' => 'fieldset',
      '#title' => $type == '*' ? t('All Types') : $type,
      '#tree' => false,
    );
    foreach ($exts as $ext => $formats) {
      $form[$type]['asset_default_formatter_' . $type . '_' . $ext] = array(
        '#type' => 'select',
        '#title' => $ext,
        '#options' => asset_formatter_options($type, $ext),
        //'#default_value' => variable_get('asset_default_formatter_'. $type . '_' . $ext, 'asset:link'),
        '#default_value' => asset_get_default_formatter($type, $ext, FALSE),
      );
      $form[$type]['asset_default_formatter_teaser_' . $type . '_' . $ext] = array(
        '#type' => 'select',
        '#title' => $ext,
        '#options' => asset_formatter_options($type, $ext),
        //'#default_value' => variable_get('asset_default_formatter_teaser_' . $type . '_' . $ext, 'asset:link'),
        '#default_value' => asset_get_default_formatter($type, $ext, TRUE),
      );
    }
  }
  return system_settings_form($form);
}

/**
 * Implementation of hook_nodeapi()
 * This is where we build the asset_node records.
 */
function asset_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  switch ($op) {
    case 'insert':
    case 'update':

      // clear previous count
      db_query('DELETE FROM {asset_node} WHERE nid=%d', $node->nid);

      // only update if using a format that includes the asset filter
      $filters = filter_list_format($node->format);
      if (!$filters['asset/0']) {
        return;
      }
      $refs = array();
      foreach (asset_get_macros($node->body) as $macro) {
        $refs[$macro['aid']]++;
      }
      foreach ($refs as $aid => $ref) {
        db_query('INSERT INTO {asset_node} (aid, nid, refs) VALUES (%d, %d, %d)', $aid, $node->nid, $ref);
      }
      break;
    case 'load':
      $result = db_query('SELECT * FROM {asset_node} WHERE nid=%d AND refs > 0', $node->nid);
      while ($asset = db_fetch_object($result)) {
        $additions['assets'][] = asset_load($asset->aid);
      }
      return $additions;
    case 'view':
      foreach ($node as $fieldname => $value) {
        if (substr($fieldname, 0, 6) == "field_") {

          // For each cck field, check if it's an asset field
          $fields = content_fields($fieldname, $node->type);
          if ($fields['type'] == "value") {

            // The asset computer name is "value"
            $assetcheck = 1;
            foreach (array_keys($node->fieldname) as $key) {

              // Add the html code for the preview
              if (!empty($node->fieldname[$key]['aid'])) {
                $node->fieldname[$key]['value'] = asset_preview($node->fieldname[$key]['aid']);
              }
            }
          }
        }
      }
      break;
  }
}

/**
 * Integrate asset with lightbox
 */
function asset_lightbox($assets, $preview = FALSE, $teaser = FALSE) {
  if (!$preview && file_exists(path_to_theme() . "/lightbox/lightbox.js")) {

    // Do not include Lightbox integration in preview mode: it breaks the jQuery fieldsets
    drupal_add_js(path_to_theme() . "/lightbox/prototype.js");
    drupal_add_js(path_to_theme() . "/lightbox/scriptaculous.js?load=effects");
    drupal_add_js(path_to_theme() . "/lightbox/lightbox.js");
    drupal_add_css(path_to_theme() . "/lightbox/lightbox.css");
  }
  $output = "";
  $is_image = array(
    'jpg',
    'jpeg',
    'png',
    'gif',
    'tif',
    'tiff',
    'bmp',
  );
  $is_audio = array(
    'mp3',
    'wma',
    'wav',
    'ogg',
    'm4a',
    'aac',
  );
  $count = 1;
  $total = 3;
  $imgpresent = 1;
  $imgcount = 0;
  $imgdisplay = 0;
  $firstimg = "";
  foreach ($assets as $asset) {
    $a = asset_load(array(
      'aid' => $asset['aid'],
    ));
    if (in_array($a->extension, $is_image)) {

      // If it's an image and imagecache configuration has been done, display the imagecached version
      $imagecache = asset_get_default_formatter('local', $a->extension, $teaser);
      if (function_exists('theme_imagecache') && substr($imagecache, 0, 11) == "imagecache:") {
        list($imagecache, $preset) = split(":", $imagecache);
        $img = theme('imagecache', $preset, $a->filepath, $asset['caption'], $asset['caption']);
      }
      else {
        $img = theme('image', $a->filepath, $asset['caption'], $asset['caption']);
      }
      $link = '<a href="' . file_create_url($a->filepath) . '" rel="lightbox[gallery]" title="' . str_replace("\"", "'", $asset['caption']);
      $link .= $asset['copyright'] ? '<br/>&#169; ' . str_replace("\"", "'", $asset['copyright']) . '"' : '"';

      // We only want to display $total thumbnails, but we need the html for the lightbox gallery
      if ($count > $total) {
        $link .= " style='display:none'";
      }
      else {
        $imgdisplay++;
      }
      if (empty($firstimg)) {
        $firstimg = $link . ">";
      }
      $link .= ">" . $img . "</a>";
      $output .= $link;
      if ($count <= $total) {
        $output .= $asset['caption'] ? "<p>" . $asset['caption'] . "</p>" : "";
        $output .= $asset['copyright'] ? "<p class='attribution'>&#169; " . $asset['copyright'] . "</p>" : "";
        $output .= "<br/>";
      }
      $imgcount++;
    }
    else {

      // Not an image so automatically asset_preview() it
      $output .= asset_preview($asset['aid']);
      $output .= $asset['caption'] ? "<p>" . $asset['caption'] . "</p>" : "";
      $output .= $asset['copyright'] ? "<p class='attribution'>&#169; " . $asset['copyright'] . "</p>" : "";
      if (in_array($a->extension, $is_audio)) {
        $output .= '<p><a href="' . file_create_url($a->filepath) . '">' . t("Download this audio file") . '</a></p>';
      }
    }
    $count++;
  }
  if (!empty($imgcount) && $imgcount > $imgdisplay) {
    $firstimg = str_replace("style='display:none'", "", $firstimg);
    $output .= t('<br/><div class="view-all-images">' . $firstimg . '%mycount </a></div>', array(
      '%mycount' => format_plural($imgcount, 'View the image', 'View all @count images'),
    ));
  }
  return $output;
}

/**
 * Implementation of hook_filter().
 */
function asset_filter($op, $delta = 0, $format = -1, $text = '') {
  switch ($op) {
    case 'list':
      return array(
        0 => t('Inline file assets'),
      );
    case 'description':
      return t('Add formatted file assets to your posts.');
    case 'process':
      foreach (asset_get_macros($text) as $unexpanded_macro => $macro) {
        $expanded_macro = asset_render_macro($macro);
        $text = str_replace($unexpanded_macro, $expanded_macro, $text);
      }
      return $text;
    default:
      return $text;
  }
}

/**
 * Implementation of hook_filter_tips().
 */
function asset_filter_tips($delta, $format, $long = false) {
  if ($long) {
    return t('Inline assets are allowed.  Use the Insert Assets link or the WYSIWYG editor button to insert the proper format.');
  }
  else {
    return t('Inline assets are allowed.');
  }
}

/**
 * Return all macros as an array.
 */
function asset_get_macros($text) {
  $m = array();
  preg_match_all('/ \\[ ( [^\\[\\]]+ )* \\] /x', $text, $matches);
  $tag_match = (array) array_unique($matches[1]);

  // Don't process duplicates.
  foreach ($tag_match as $macro) {
    $current_macro = '[' . $macro . ']';
    $param = array_map('trim', explode('|', $macro));
    $func_name = array_shift($param);

    // The first macro param is assumed to be the function name.

    //$num_params = count($param); // Get the number of parameters
    if ($func_name == 'asset') {
      $vars = array();
      foreach ($param as $p) {
        $pos = strpos($p, '=');
        $varname = substr($p, 0, $pos);
        $varvalue = substr($p, $pos + 1);
        $vars[$varname] = $varvalue;
      }

      // the full unaltered filter string is the key for the array of filter attributes
      $m[$current_macro] = $vars;
    }
  }
  return $m;
}

/** 
 * build html from atrributes array.
 * 
 * @param $attr
 *   Array of attributes parsed from filter macro.
 */
function asset_render_macro($attr = array()) {
  $asset = asset_load($attr['aid']);
  $asset->title = $attr['title'] ? $attr['title'] : $asset->title;
  if ($attr['formatter']) {
    $content = module_invoke($attr['formatter'], 'asset_formatter', 'render', $asset, $attr);
    return theme('asset', $content, $attr);
  }
  else {
    return theme('asset_render_default', $asset);
  }
}

/**
 * Build a macro from the specified attributes.
 */
function asset_build_macro($attr = array()) {
  $macro = '[asset';
  foreach ($attr as $k => $v) {
    $macro .= '|' . $k . '=' . $v;
  }
  $macro .= ']';
  return $macro;
}

/**
 * Utility function to retrieve a list of all available formatters.
 * 
 * @return array
 *     returns an array keyed by filetype(extension) with elements as arrays of format information.
 */
function asset_get_formatters($reset = FALSE) {
  static $formatters;
  if (!isset($formatters) || $reset) {
    if (!$reset && ($cache = cache_get('asset_formatters')) && !empty($cache->data)) {
      $formatters = unserialize($cache->data);
    }
    else {
      $formatters = array();
      foreach (module_implements('asset_formatter') as $module) {
        $list = module_invoke($module, 'asset_formatter', 'info');
        foreach ((array) $list as $key => $data) {
          $data['module'] = $module;
          $data['format'] = $key;
          foreach ($data['types'] as $type => $exts) {
            foreach ($exts as $ext) {
              $formatters[$type][$ext][] = $data;
            }
          }
        }
      }
      cache_set('asset_formatters', 'cache', serialize($formatters));
    }
  }
  return $formatters;
}

/**
 * Utility function to return an array of available formatters for a file suitable for FAPI #options
 * 
 * @param $filename
 *    Filename to retrieve options for.  Will also work with just an extension.
 */
function asset_formatter_options($type = '*', $filename = null) {
  $pos = strrpos($filename, '.');
  if ($pos === false) {

    // allow for case where extension is passed instead of filename
    $ext = $filename;
  }
  else {
    $ext = substr($filename, $pos + 1);
  }
  $formatters = asset_get_formatters();
  $options = array();
  if (is_array($formatters[$type][$ext])) {
    foreach ($formatters[$type][$ext] as $formatter) {
      $options[$formatter['module'] . ':' . $formatter['format']] = $formatter['name'];
    }
  }
  if (is_array($formatters[$type]['*'])) {
    foreach ($formatters[$type]['*'] as $formatter) {
      $options[$formatter['module'] . ':' . $formatter['format']] = $formatter['name'];
    }
  }
  if (is_array($formatters['*']['*'])) {
    foreach ($formatters['*']['*'] as $formatter) {
      $options[$formatter['module'] . ':' . $formatter['format']] = $formatter['name'];
    }
  }
  return $options;
}

/**
 * Menu callback to load the asset popup window.
 */
function asset_wizard() {

  // all wizard related functionality first comes through this function so load the wizard inc
  require_once drupal_get_path('module', 'asset') . '/asset_wizard.inc';
  drupal_add_js(array(
    'asset' => array(
      'basePath' => base_path(),
    ),
  ), 'setting');
  drupal_add_js(drupal_get_path('module', 'asset') . '/asset.js');
  drupal_add_css(drupal_get_path('module', 'asset') . '/asset_wizard.css');
  list($sites, $site, $lost) = split("/", drupal_get_path('module', 'asset'), 3);
  $theme = variable_get('asset_wizard_theme', drupal_get_path('module', 'asset') . '/themes/default/asset_wizard.css');
  drupal_add_css($theme);
  switch (arg(2)) {
    case 'textarea':
      drupal_add_js(drupal_get_path('module', 'asset') . '/asset_textarea.js');
      break;
    case 'textfield':
      drupal_add_js(drupal_get_path('module', 'asset') . '/asset_textfield.js');
      break;
    case 'tinymce':
      drupal_add_js(drupal_get_path('module', 'tinymce') . '/tinymce/jscripts/tiny_mce/tiny_mce_popup.js');
      drupal_add_js(drupal_get_path('module', 'asset') . '/tinymce/asset_tinymce.js');
      break;
  }
  $output = drupal_get_form('asset_wizard_form');
  ob_end_clean();
  print theme('asset_popup', $output);
  exit;
}

/**
 * Implementation of hook_elements
 * This is where we add the link to textareas
 */
function asset_elements() {
  $type['textarea'] = array(
    '#process' => array(
      'asset_textarea' => array(),
    ),
  );
  return $type;
}

/**
 * The #process callback function for the textareas
 */
function asset_textarea($element) {
  if (_asset_page_match()) {
    $output = theme('asset_textarea_link', $element);
    $element['#suffix'] .= $output;
    if (module_exists('tinymce')) {
      drupal_add_js(drupal_get_path('module', 'asset') . '/tinymce/asset_tinymce_helper.js');
    }
  }
  return $element;
}

/**
 * Should we show the insert access link, determined by admin setting
 * Borrowed from tinymce.module
 *
 * @return
 *   TRUE if can render, FALSE if not allowed.
 */
function _asset_page_match() {
  $page_match = FALSE;
  if (!user_access('create assets') && !user_access('administer assets')) {
    return $page_match;
  }
  $access_option = variable_get('asset_access_option', 1);
  $access_pages = variable_get('asset_access_pages', "node/add/*\nnode/*/edit");
  if ($access_pages) {

    // If the PHP option wasn't selected
    if ($access_option < 2) {
      $path = drupal_get_path_alias($_GET['q']);
      $regexp = '/^(' . preg_replace(array(
        '/(\\r\\n?|\\n)/',
        '/\\\\\\*/',
        '/(^|\\|)\\\\<front\\\\>($|\\|)/',
      ), array(
        '|',
        '.*',
        '\\1' . preg_quote(variable_get('site_frontpage', 'node'), '/') . '\\2',
      ), preg_quote($access_pages, '/')) . ')$/';
      $page_match = !($access_option xor preg_match($regexp, $path));
    }
    else {
      $page_match = drupal_eval($access_pages);
    }
  }
  elseif ($access_option == 0) {
    $page_match = TRUE;
  }
  return $page_match;
}

/**
 * Menu Callback from javascript to print an assets preview
 */
function asset_js_preview($aid, $show_details = true, $return = false) {
  if (!isset($aid)) {
    exit;
  }
  $asset = asset_load($aid);
  $formatters = asset_get_formatters();
  if (isset($formatters[$asset->type][$asset->extension][0])) {
    $format = $formatters[$asset->type][$asset->extension][0];
  }
  elseif (isset($formatters[$asset->type]['*'][0])) {
    $format = $formatters[$asset->type]['*'][0];
  }
  else {
    $format = $formatters['*']['*'][0];
  }
  $output .= '<div>' . $asset->filename . '</div>';
  $output .= asset_preview($asset->aid);
  if ($show_details) {
    $details[t('File Size')] = format_size($asset->filesize);
    $details = array_merge($details, (array) module_invoke($format['module'], 'asset_formatter', 'details', $asset, $format));
    foreach ($details as $label => $value) {
      $output .= '<div><strong>' . check_plain($label) . '</strong>: ' . check_plain($value) . '</div>';
    }
  }
  if ($return) {
    return $output;
  }
  print $output;
  exit;
}

/**
 * Build a preview of an asset based on module and format options.  If no module
 * and format info is given then the default teaser formatter is used.
 */
function asset_preview($aid, $module = NULL, $format = NULL) {
  $asset = asset_load($aid);
  if (!$module || !$format) {
    $formatter = asset_get_default_formatter($asset->type, $asset->extension, TRUE);
    list($module, $format) = explode(':', $formatter);
  }
  $output = module_invoke($module, 'asset_formatter', 'preview', $asset, array(
    'format' => $format,
  ));
  return $output;
}

/**
 * Callback function to output an image for preview of an asset.
 */
function asset_img_preview($aid, $module = NULL, $format = NULL) {
  $asset = asset_load($aid);
  if (!$module || !$format) {
    $formatter = asset_get_default_formatter($asset->type, $asset->extension, TRUE);
    list($module, $format) = explode(':', $formatter);
  }
  $src = module_invoke($module, 'asset_formatter', 'img', $asset, array(
    'format' => $format,
  ));

  // We're not useing drupal_goto because filenames will have the language code prepended
  // return drupal_goto($src);
  $src = substr($src, 0, 5) != "http:" ? base_path() . $src : $src;
  return header('location: ' . $src);
}

/**
 * Modified version of file_transfer()
 * 
 * Only output image formats and do not require src to be in file_directory_path
 */
function asset_img_output($src) {
  ob_end_clean();
  $mimes = array(
    'jpg' => 'image/jpeg',
    'gif' => 'image/gif',
    'png' => 'image/x-png',
  );
  $info = pathinfo($src);
  if (!$mimes[$info['extension']]) {
    return drupal_not_found();
  }
  header('Content-type: ' . $mimes[$info['extension']]);
  if ($fd = fopen($src, 'rb')) {
    while (!feof($fd)) {
      print fread($fd, 1024);
    }
    fclose($fd);
  }
  else {
    drupal_not_found();
  }
  exit;
}

/**
 * Wrapper for file_check_directory that also checks/adds a matching asset
 */
function asset_check_directory(&$directory, $mode = 0, $form_item = NULL, $form_values = array()) {
  $return = file_check_directory(file_create_path($directory), $mode, $form_item);
  if ($return && $mode && !empty($form_values)) {
    $asset = asset_load(array(
      'dirname' => $form_values['parent'],
      'filename' => $form_values['title'],
    ));
    if (!$asset) {
      $asset = new stdClass();
      $asset->filepath = $directory;
      $asset->filesize = 0;
      $asset->type = 'directory';
      asset_save($asset, $form_values);
    }
  }
  return $return;
}

/**
 * Get the default formatter for a given type and extension
 */
function asset_get_default_formatter($type, $ext, $teaser = FALSE) {
  $prefix = 'asset_default_formatter_' . ($teaser ? 'teaser_' : '');
  $vars = array(
    $prefix . $type . '_' . $ext,
    $prefix . $type . '_*',
    $prefix . '*_*',
  );
  foreach ($vars as $var) {
    if ($formatter = variable_get($var, false)) {
      break;
    }
  }

  // if var is not set, then cascade through possible formatters to find a suitable one
  if (!$formatter) {
    $formatters = asset_get_formatters();
    if (isset($formatters[$type][$ext][0])) {
      $format = $formatters[$type][$ext][0];
    }
    elseif (isset($formatters[$type]['*'][0])) {
      $format = $formatters[$type]['*'][0];
    }
    else {
      $format = $formatters['*']['*'][0];
    }
    $formatter = $format['module'] . ':' . $format['format'];
  }
  return $formatter;
}

/**
 * Helper function to build a query string from an array
 */
function asset_build_query($data) {
  foreach ($data as $k => $v) {
    $items[] = "{$k}={$v}";
  }
  return join('&', $items);
}

/**
 * wrapper around pathinfo() that strips file_directory_path from path and .
 * from dirname
 */
function asset_pathinfo($path) {
  $path = trim(str_replace(file_directory_path(), '', $path), '/');
  $info = pathinfo($path);
  if ($info['dirname'] == '.') {
    $info['dirname'] = '';
  }
  return $info;
}

/** 
 * Asset API Implementation ===================================================
 */

/**
 * Implementation of hook_asset_formatter().
 */
function asset_asset_formatter($op = 'info', $asset = NULL, $attr = array()) {
  switch ($op) {
    case 'info':
      $formats['link'] = array(
        'name' => t('Link'),
        'types' => array(
          '*' => array(
            '*',
          ),
        ),
        'description' => t('A simple download link.'),
      );
      $formats['image'] = array(
        'name' => t('Image'),
        'types' => array(
          'local' => array(
            'jpg',
            'gif',
            'png',
          ),
        ),
        'description' => t('The full-size image.'),
      );
      return $formats;
    case 'options':
      switch ($attr['format']) {
        case 'image':
          $info = image_get_info(file_create_path($asset->filepath));
          $form['height'] = array(
            '#type' => 'textfield',
            '#title' => t('Height'),
            '#size' => '10',
            '#default_value' => !isset($_GET['height']) ? $info['height'] : filter_xss($_GET['height']),
          );
          $form['width'] = array(
            '#type' => 'textfield',
            '#title' => t('Width'),
            '#size' => '10',
            '#default_value' => !isset($_GET['width']) ? $info['width'] : filter_xss($_GET['width']),
          );
          $form['resizable'] = array(
            '#type' => 'hidden',
            '#value' => 'true',
          );
          return $form;
        default:
          return array();
      }
      break;
    case 'render':
      switch ($attr['format']) {
        case 'image':
          $img_attributes = array(
            'title' => $attr['title'],
            'alt' => $attr['title'],
          );
          if ($attr['height']) {
            $img_attributes['height'] = $attr['height'];
          }
          if ($attr['width']) {
            $img_attributes['width'] = $attr['width'];
          }
          return '<img src="' . file_create_url($asset->filepath) . '" ' . drupal_attributes($img_attributes) . ' />';
        default:
          return theme('asset_render_default', $asset);
      }
      break;
    case 'preview':
      switch ($attr['format']) {
        case 'image':
          return theme('image', file_create_path($asset->filepath), '', '', array(
            'width' => '100',
          ), false);
        case 'link':
          return theme('asset_render_default', $asset);
      }
      break;
    case 'details':
      switch ($attr['format']) {
        case 'image':
          $info = image_get_info(file_create_path($asset->filepath));
          return array(
            t('Width') => $info['width'] . 'px',
            t('Height') => $info['height'] . 'px',
          );
      }
      return array();
    case 'img':
      switch ($attr['format']) {
        case 'image':
          return file_create_url($asset->filepath);
        case 'link':
        default:

          // when we get around to building icons.
          $icon = drupal_get_path('module', 'asset') . '/icons/' . $asset->extension . '.png';
          if (file_exists($icon)) {
            return $icon;
          }

          // if all else fails send back a transparent gif so the default bg image shows
          return drupal_get_path('module', 'asset') . '/transparent.gif';
      }
      break;
  }
}

/**
 * Implementation of hook_asset_type().
 */
function asset_asset_type($op = 'info', $delta = 0, $form_values = array()) {
  switch ($op) {
    case 'info':
      $info['upload'] = array(
        'value' => t('Upload'),
        'title' => t('Upload a new file.'),
        'src' => drupal_get_path('module', 'asset') . '/lullacons/doc-option-add.png',
      );
      $info['directory'] = array(
        'value' => t('New Folder'),
        'title' => t('Create a new folder.'),
        'src' => drupal_get_path('module', 'asset') . '/lullacons/folder-option-add.png',
      );
      $info['directory-del'] = array(
        'value' => t('Delete Folder'),
        'title' => t('Delete the current folder.'),
        'src' => drupal_get_path('module', 'asset') . '/lullacons/folder-option-remove.png',
      );
      return $info;
    case 'form':
      $form['module'] = array(
        '#type' => 'value',
        '#value' => 'asset',
      );
      if ($delta == 'upload') {
        $form['upload'] = array(
          '#type' => 'file',
          '#title' => t('Upload a File'),
          '#size' => 35,
          '#weight' => -1,
        );
      }
      if (empty($_SESSION['asset_op'])) {

        // Don't allow the asset cck to select a width/size or imagecache preset
        $form['#redirect'] = "node/1";
      }
      $form['#attributes']['enctype'] = 'multipart/form-data';
      return $form;
    case 'validate':

      // must return a valid asset aid
      if ($delta == 'upload') {
        if ($file = file_check_upload('upload')) {
          $parent_tmp = $form_values['parent'] ? $form_values['parent'] . '/' : $form_values['parent'];
          $path = file_create_path($parent_tmp . $file->filename);
          if ($file = file_save_upload('upload', $path)) {
            $asset = asset_save($file, $form_values);
            drupal_set_message(t("The file {$file->filename} has been successfully uploaded."));
            if (isset($_SESSION['asset_fieldname'])) {
              drupal_goto(filter_xss($_GET['q']), 'dir=' . filter_xss($_GET['dir']));
            }
            else {
              return $asset->aid;
            }
          }
          else {
            form_set_error('upload', 'Error saving file to <em>' . $path . '</em>');
          }
        }
        else {
          form_set_error('upload', 'Error uploading file</em>');
        }
      }
      else {
        $parent_tmp = $form_values['parent'] ? $form_values['parent'] . '/' : $form_values['parent'];
        $dir = $parent_tmp . $form_values['title'];
        if (asset_check_directory($dir, FILE_CREATE_DIRECTORY)) {
          $query = $_GET;
          unset($query['q']);
          $query['dir'] = trim(str_replace(file_create_path(), '', $dir), '/');
          drupal_goto($_GET['q'], asset_build_query($query));
        }
        else {
          form_set_error('title', t('Error creating directory.'));
        }
      }
      break;
    case 'submit':
      break;
  }
}
function asset_file_download($file) {
  global $user;
  $filename = basename($file);
  list($path) = split("/" . $filename, $file);
  $public = db_result(db_query("SELECT status FROM {asset} WHERE type='local' AND dirname='%s' AND filename='%s' LIMIT 1", $path, $filename));
  if ($public || $user->uid == 1) {
    $mime = function_exists(mime_content_type) ? mime_content_type($file) : "";
    return array(
      'Content-type:' . $mime,
    );
  }
  else {
    $aid = db_result(db_query("SELECT aid FROM {asset} WHERE type='local' AND dirname='%s' AND filename='%s' LIMIT 1", $path, $filename));
    $roles = db_query("SELECT rid, status FROM {asset_role} WHERE aid=%d", $aid);
    while ($role = db_fetch_object($roles)) {
      if ($role->status && $user->roles[$role->rid]) {
        $mime = function_exists(mime_content_type) ? mime_content_type($file) : "";
        return array(
          'Content-type:' . $mime,
        );
      }
    }
  }
}

/**
 * Theme Functions ============================================================
 */

/**
 * Theme rendered assets
 */
function theme_asset($content, $attributes) {
  if ($attributes['formatter'] == "imagecache" || $attributes['format'] == "image") {

    // We don't put images in a div because IE6 doesn't like <a><div><img/></div></a></>
    $align = 'asset-align-' . ($attributes['align'] ? $attributes['align'] : 'none');
    if (strpos($content, 'class')) {
      $content = str_replace("class=\"", "class=\"" . $align . " ", $content);
    }
    else {
      $content = str_replace("/>", "class=\"" . $align . "\"/>", $content);
    }
    return $content;
  }
  else {
    $class = 'asset-' . $attributes['formatter'] . '-' . $attributes['format'];
    $class .= ' asset-align-' . ($attributes['align'] ? $attributes['align'] : 'none');
    $output = '<span class="' . $class . '">' . $content . '</span>';
    return $output;
  }
}

/**
 * Theme the wizard theme selection table.
 */
function theme_asset_wizard_theme_form($form) {
  foreach (element_children($form) as $filename) {
    if (file_exists(dirname($filename) . '/asset_wizard.png')) {
      $screenshot = theme('image', dirname($filename) . '/asset_wizard.png');
    }
    else {
      $screenshot = 'No screenshot available';
    }
    $rows[] = array(
      $screenshot,
      '<strong>' . basename(dirname($filename)) . '</strong><br/>' . $filename,
      drupal_render($form[$filename]),
    );
  }
  return theme('table', array(
    t('Screenshot'),
    t('Name'),
    '',
  ), $rows);
}
function theme_asset_admin_formatter_defaults($form) {
  $formatters = asset_get_formatters();
  foreach ($formatters as $type => $exts) {
    $rows = array();
    foreach ($exts as $ext => $formats) {
      unset($form[$type]['asset_default_formatter_' . $type . '_' . $ext]['#title']);
      unset($form[$type]['asset_default_formatter_teaser_' . $type . '_' . $ext]['#title']);
      $rows[] = array(
        $ext,
        drupal_render($form[$type]['asset_default_formatter_' . $type . '_' . $ext]),
        drupal_render($form[$type]['asset_default_formatter_teaser_' . $type . '_' . $ext]),
      );
    }
    $form[$type]['#value'] = theme('table', array(
      '',
      'Full Page',
      'Teaser',
    ), $rows);
  }
  return drupal_render($form);
}

/**
 * Default rendering available to all assets.
 */
function theme_asset_render_default($asset) {
  if (substr($asset->url, 0, 5) != "http:") {
    $asset->url = url($asset->url);
  }
  $asset->title = $asset->title ? $asset->title : $asset->filename;
  return '<a href="' . $asset->url . '" class="asset">' . $asset->title . '</a>';
}

/**
 * Theme the textarea link
 */
function theme_asset_textarea_link($element) {
  $link = l(t('Insert Assets'), 'asset/wizard/textarea', array(
    'class' => 'asset-textarea-link',
    'id' => 'asset-link-' . $element['#id'],
    'onclick' => "window.open(this.href, 'asset_textarea_link', 'width=614,height=400,scrollbars=yes,status=yes,resizable=yes,toolbar=no,menubar=no'); return false",
  ), 'textarea=' . $element['#name']);
  $output .= '<div>' . $link . '</div>';
  return $output;
}

Functions

Namesort descending Description
asset_admin_formatter_defaults Menu callback for selection of default formatting options.
asset_admin_settings Admin Settings
asset_asset_formatter Implementation of hook_asset_formatter().
asset_asset_type Implementation of hook_asset_type().
asset_build_macro Build a macro from the specified attributes.
asset_build_query Helper function to build a query string from an array
asset_check_directory Wrapper for file_check_directory that also checks/adds a matching asset
asset_elements Implementation of hook_elements This is where we add the link to textareas
asset_file_download
asset_filter Implementation of hook_filter().
asset_filter_tips Implementation of hook_filter_tips().
asset_formatter_options Utility function to return an array of available formatters for a file suitable for FAPI #options
asset_get_default_formatter Get the default formatter for a given type and extension
asset_get_formatters Utility function to retrieve a list of all available formatters.
asset_get_macros Return all macros as an array.
asset_img_output Modified version of file_transfer()
asset_img_preview Callback function to output an image for preview of an asset.
asset_js_preview Menu Callback from javascript to print an assets preview
asset_lightbox Integrate asset with lightbox
asset_load Load an asset object from db and set some default properties. Taken almost exactly from node_load to utilize caching and assetapi load hook
asset_menu Implementation of hook_menu()
asset_nodeapi Implementation of hook_nodeapi() This is where we build the asset_node records.
asset_pathinfo wrapper around pathinfo() that strips file_directory_path from path and . from dirname
asset_perm Implementation of hook_perm().
asset_preview Build a preview of an asset based on module and format options. If no module and format info is given then the default teaser formatter is used.
asset_render_macro build html from atrributes array.
asset_save Persist an asset object to the db
asset_textarea The #process callback function for the textareas
asset_wizard Menu callback to load the asset popup window.
theme_asset Theme rendered assets
theme_asset_admin_formatter_defaults
theme_asset_render_default Default rendering available to all assets.
theme_asset_textarea_link Theme the textarea link
theme_asset_wizard_theme_form Theme the wizard theme selection table.
_asset_include
_asset_page_match Should we show the insert access link, determined by admin setting Borrowed from tinymce.module

Constants