name, '', 0, 6); if (module_exists($module)) { require_once ("./$file->filename"); } } } /** * Implementation of hook_menu() */ function asset_menu($may_cache) { if ($may_cache) { $items[] = array ( 'type' => MENU_CALLBACK, 'title' => t('Asset Wizard'), 'path' => 'asset/wizard', 'callback' => 'asset_wizard', 'access' => user_access('create assets'), ); $items[] = array ( 'type' => MENU_CALLBACK, 'path' => 'asset/js/preview', 'callback' => 'asset_js_preview', 'access' => user_access('create 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('administer assets'), ); } else { // load all of the necessary includes _asset_include(); // provide a way for formatters to include js/css since render result gets cached // TODO: investigate possibly better ways to do this 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()) { $asset->filepath = trim(str_replace(file_directory_path(),'',$asset->filepath),'/'); $info = pathinfo($asset->filepath); if($info['dirname'] == '.'){ $info['dirname'] = ''; } $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) VALUE (%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); } // Retrieve the asset. $asset = db_fetch_object(db_query('SELECT a.* FROM {asset} a WHERE ' . $cond, $arguments)); if(!$asset){ return false; } $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($asset->dirname . '/' . $asset->filename); $asset->url = file_create_url($asset->dirname . '/' . $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 TRUE (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. is the front page.If the PHP-mode is chosen, enter PHP code between . 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('#value' => '

This form is currently just a placeholder. The values are not used anywhere yet.

'); $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'), ); $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'), ); } } 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) { // must do this on submit rather than update or insert because we want the // pre filtered node->body case 'submit': // 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->aid; } return (array) $additions; } } /** * 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']); 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(drupal_get_path('module', 'asset') . '/asset.js'); drupal_add_css(drupal_get_path('module', 'asset') . '/asset_wizard.css'); $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 '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; } 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; $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)/', '/\\\\\*/', '/(^|\|)\\\\($|\|)/'), 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); } } // No pages were specified to block so show on all else { $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) { $asset = asset_load($aid); $formatters = asset_get_formatters(); if (isset ($formatters[$asset->type][$asset->extension][0])) { $format = $formatters[$asset->type][$asset->extension][0]; } else if( isset($formatters[$asset->type]['*'][0]) ){ $format = $formatters[$asset->type]['*'][0]; } else { $format = $formatters['*']['*'][0]; } $output .= '
' . $asset->filename . '
'; $output .= module_invoke($format['module'], 'asset_formatter', 'preview', $asset, $format); 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 .= '
' . check_plain($label) . ': ' . check_plain($value) . '
'; } } if($return){ return $output; } print $output; exit; } /** * 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) { $src = module_invoke($module, 'asset_formatter', 'img', $asset, array ('format' => $format)); } if (!$src) { $src = module_invoke('asset', 'asset_formatter', 'img', $asset); } if(strpos($src, 'http') === 0){ return drupal_goto($src); } return asset_img_output($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){ $return = file_check_directory(file_create_path($directory), $mode, $form_item); $pathinfo = asset_pathinfo($directory); if($return && ($mode & FILE_CREATE_DIRECTORY)){ $asset = asset_load(array('dirname'=> $pathinfo['dirname'], 'filename' => $pathinfo['filename'])); if(!$asset){ $asset = new stdClass(); $asset->filepath = $directory; $asset->filesize = 0; $asset->type = 'directory'; asset_save($asset); } } 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(!$formatter){ $formatter = 'asset:link'; } 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' => $info['height'], ); $form['width'] = array ( '#type' => 'textfield', '#title' => t('Width'), '#size' => '10', '#default_value' => $info['width'], ); $form['resizable'] = array ( '#type' => 'hidden', '#value' => 'true', ); return $form; default : return array(); } break; case 'render': switch ($attr['format']) { case 'image' : $img_attributes = array (); if ($attr['height']) { $img_attributes['height'] = $attr['height']; } if ($attr['width']) { $img_attributes['width'] = $attr['width']; } return ''; 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; } 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_path($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', ); 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, ); } $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')){ $path = file_create_path($form_values['parent'].'/'.$file->filename); if($file = file_save_upload('upload', $path)){ $asset = asset_save($file, $form_values); return $asset->aid; }else{ form_set_error('upload','Error saving file to '.$path.''); } }else{ form_set_error('upload','Error uploading file'); } }else{ $dir = join(array($form_values['parent'],$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; } } /** * Theme Functions ============================================================ */ /** * Theme rendered assets */ function theme_asset($content, $attributes){ $class = 'asset-'.$attributes['formatter'].'-'.$attributes['format']; $class .= ' asset-align-'. ($attributes['align'] ? $attributes['align'] : 'none'); $output = '
'.$content.'
'; 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, ''.basename(dirname($filename)).'
'.$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) { return '' . ($asset->title ? $asset->title : $asset->filename) . ''; } /** * 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=600,height=400,scrollbars=yes,status=yes,resizable=yes,toolbar=no,menubar=no'); return false", ), 'textarea='.$element['#name']); $output .= '
'.$link.'
'; return $output; }