diff options
| -rw-r--r-- | LibertyAttachable.php | 51 | ||||
| -rw-r--r-- | admin/admin_liberty_inc.php | 27 | ||||
| -rw-r--r-- | admin/schema_inc.php | 1 | ||||
| -rw-r--r-- | attachment_uploader.php | 44 | ||||
| -rw-r--r-- | edit_storage_inc.php | 32 | ||||
| -rw-r--r-- | plugins/storage.bitfile.php | 18 | ||||
| -rw-r--r-- | templates/admin_liberty.tpl | 14 | ||||
| -rw-r--r-- | templates/attachment_uploader.tpl | 23 | ||||
| -rw-r--r-- | templates/attachment_uploader_inc.tpl | 24 | ||||
| -rw-r--r-- | templates/edit_storage.tpl | 2 | ||||
| -rw-r--r-- | templates/edit_storage_list.tpl | 6 |
11 files changed, 193 insertions, 49 deletions
diff --git a/LibertyAttachable.php b/LibertyAttachable.php index 0b36407..e5b22e7 100644 --- a/LibertyAttachable.php +++ b/LibertyAttachable.php @@ -3,7 +3,7 @@ * Management of Liberty Content * * @package liberty - * @version $Header: /cvsroot/bitweaver/_bit_liberty/LibertyAttachable.php,v 1.73 2007/04/13 17:57:39 nickpalmer Exp $ + * @version $Header: /cvsroot/bitweaver/_bit_liberty/LibertyAttachable.php,v 1.74 2007/04/16 14:03:13 nickpalmer Exp $ * @author spider <spider@steelsun.com> */ // +----------------------------------------------------------------------+ @@ -188,8 +188,14 @@ Disable for now - instead fend off new uploads once quota is exceeded. Need a ni global $gBitSystem; // Support for single bitfile upload $this->verifyAttachment( $pParamHash, 'upload' ); - if ($gBitSystem->isFeatureActive('liberty_multiple_attachments')) { - $pParamHash['upload_arrays'] .= ',uploads'; + // Auto add uploads for multiple attachment style + if ($gBitSystem->getConfig('liberty_attachment_style') == "multiple") { + if (empty($pParamHash['upload_arrays'])) { + $pParamHash['upload_arrays'] = 'uploads'; + } + else { + $pParamHash['upload_arrays'] .= ',uploads'; + } } // Support for multiple arrays of uploads. if (!empty($pParamHash['upload_arrays'])) { @@ -251,8 +257,16 @@ Disable for now - instead fend off new uploads once quota is exceeded. Need a ni $storeRow['content_id'] = $pParamHash['content_id']; // copy in content_id } - $storeRow['content_id'] = $pParamHash['content_id']; // copy in content_id - $storeRow['user_id'] = $pParamHash['user_id']; // copy in the user_id + if (!empty($pParamHash['content_id'])) { + $storeRow['content_id'] = $pParamHash['content_id']; // copy in content_id + } + if (!empty($pParamHash['user_id'])) { + $storeRow['user_id'] = $pParamHash['user_id']; // copy in the user_id + } + else { + $storeRow['user_id'] = $gBitUser->mUserId; + } + // do we have a verify function for this storage type, and do things verify? $verifyFunc = $gLibertySystem->getPluginFunction( $guid, 'verify_function' ); if( $verifyFunc && $verifyFunc( $storeRow ) ) { @@ -260,8 +274,10 @@ Disable for now - instead fend off new uploads once quota is exceeded. Need a ni $storeRow['upload']['attachment_id'] = $storeRow['attachment_id']; $sql = "INSERT INTO `".BIT_DB_PREFIX."liberty_attachments` ( `attachment_id`, `attachment_plugin_guid`, `foreign_id`, `user_id` ) VALUES ( ?, ?, ?, ? )"; $rs = $this->mDb->query( $sql, array( $storeRow['attachment_id'], $storeRow['plugin_guid'], (int)$storeRow['foreign_id'], $storeRow['user_id'] ) ); - $sql = "INSERT INTO `".BIT_DB_PREFIX."liberty_attachments_map` (attachment_id, content_id) VALUES (?, ?)"; - $rs = $this->mDb->query($sql, array( $storeRow['attachment_id'], $storeRow['content_id'])); + if (!empty($storeRow['content_id'])) { + $sql = "INSERT INTO `".BIT_DB_PREFIX."liberty_attachments_map` (attachment_id, content_id) VALUES (?, ?)"; + $rs = $this->mDb->query($sql, array( $storeRow['attachment_id'], $storeRow['content_id'])); + } // if we have uploaded a file, we can take care of that generically if( is_array( $storeRow['upload'] ) && !empty( $storeRow['upload']['size'] ) ) { @@ -269,7 +285,7 @@ Disable for now - instead fend off new uploads once quota is exceeded. Need a ni $ext = substr( $storeRow['upload']['name'], strrpos( $storeRow['upload']['name'], '.' ) + 1 ); $storeRow['upload']['type'] = $gBitSystem->lookupMimeType( $ext ); } - $storeRow['upload']['dest_path'] = $this->getStorageBranch( $storeRow['attachment_id'], $pParamHash['user_id'], $this->getStorageSubDirName() ); + $storeRow['upload']['dest_path'] = $this->getStorageBranch( $storeRow['attachment_id'], $storeRow['user_id'], $this->getStorageSubDirName() ); if (!empty( $pParamHash['thumbnail_sizes'] ) ) { $storeRow['upload']['thumbnail_sizes'] = $pParamHash['thumbnail_sizes']; } @@ -343,14 +359,16 @@ Disable for now - instead fend off new uploads once quota is exceeded. Need a ni } // Store attachments only not the LibertyContent bits - function storeAttachments( &$pParamHash ) { + function storeAttachments( &$pParamHash, $pExisting = TRUE ) { $this->mDb->StartTrans(); if ($this->verifyAttachments( $pParamHash ) && !empty( $pParamHash['STORAGE'] ) && count( $pParamHash['STORAGE'] )) { $this->storeNewAttachments($pParamHash); } $this->mDb->CompleteTrans(); - $this->storeExistingAttachments($pParamHash); + if ($pExisting) { + $this->storeExistingAttachments($pParamHash); + } return( count( $this->mErrors ) == 0 ); } @@ -369,7 +387,7 @@ Disable for now - instead fend off new uploads once quota is exceeded. Need a ni // initialise some variables $attachments = $ret = $bindVars = array(); - $whereSql = ''; + $whereSql = $joinSql = $selectSql = ''; // only admin may view attachments from other users if( !$gBitUser->isAdmin() ) { @@ -384,12 +402,13 @@ Disable for now - instead fend off new uploads once quota is exceeded. Need a ni if( !empty( $pListHash['content_id'] ) ) { $whereSql .= empty( $whereSql ) ? ' WHERE ' : ' AND '; - $whereSql .= " la.content_id = ? "; + $whereSql .= " lam.content_id = ? "; + $selectSql .= " , lam.content_id "; + $joinSql .= " INNER JOIN `".BIT_DB_PREFIX."liberty_attachments_map` lam ON (la.`attachment_id` = lam.`attachment_id`) "; $bindVars[] = $pListHash['content_id']; } - $query = "SELECT la.* FROM `".BIT_DB_PREFIX."liberty_attachments` la INNER JOIN `".BIT_DB_PREFIX."users_users` uu ON(la.`user_id` = uu.`user_id`) $whereSql"; - + $query = "SELECT la.* $selectSql FROM `".BIT_DB_PREFIX."liberty_attachments` la INNER JOIN `".BIT_DB_PREFIX."users_users` uu ON(la.`user_id` = uu.`user_id`) $joinSql $whereSql"; $result = $this->mDb->query( $query, $bindVars, $pListHash['max_records'], $pListHash['offset'] ); while( $res = $result->fetchRow() ) { $attachments[] = $res; @@ -397,7 +416,7 @@ Disable for now - instead fend off new uploads once quota is exceeded. Need a ni foreach( $attachments as $attachment ) { if( $loadFunc = $gLibertySystem->getPluginFunction( $attachment['attachment_plugin_guid'], 'load_function' )) { - $ret[] = $loadFunc( $attachment ); + $ret[$attachment['attachment_id']] = $loadFunc( $attachment ); } } @@ -405,7 +424,7 @@ Disable for now - instead fend off new uploads once quota is exceeded. Need a ni $query = "SELECT COUNT(la.*) FROM `".BIT_DB_PREFIX."liberty_attachments` la INNER JOIN `".BIT_DB_PREFIX."users_users` uu ON(la.`user_id` = uu.`user_id`) - $whereSql + $joinSql $whereSql "; $pListHash['cant'] = $this->mDb->getOne( $query, $bindVars ); diff --git a/admin/admin_liberty_inc.php b/admin/admin_liberty_inc.php index 3e57a61..563618c 100644 --- a/admin/admin_liberty_inc.php +++ b/admin/admin_liberty_inc.php @@ -16,10 +16,6 @@ $formLibertyFeatures = array( 'label' => 'External image cache', 'note' => 'Enabling this will download and cache external images that are included.', ), - "liberty_multiple_attachments" => array( - 'label' => 'Allow Multiple Attachments', - 'note' => 'Allow multiple attachments in a single upload.', - ), ); if( $gBitSystem->isPackageActive( 'quota' ) ) { @@ -37,6 +33,23 @@ if( $gBitSystem->isPackageActive( 'protector' ) ) { } $gBitSmarty->assign( 'formLibertyFeatures', $formLibertyFeatures ); +$formLibertyAttachmentStyle = array( + "standard" => array( + 'label' => 'Use Standard Attachment System', + 'note' => 'Allows a single upload when content is saved.', + ), + "multiple" => array( + 'label' => 'Allow Multiple Attachments', + 'note' => 'Allow multiple attachments in a single upload.', + ), + "ajax" => array( + 'label' => 'Allow Ajax Attachments', + 'note' => 'Allow Ajax attachments where attachment is made before save so attachment id can be used in current edit.', + ), +); +$gBitSmarty->assign( 'formLibertyAttachmentStyle', $formLibertyAttachmentStyle); + + $cacheTimes = array( 0 => tra( "(no cache)" ), 60 => "1 ".tra( "minute" ), @@ -87,9 +100,9 @@ if( !empty( $_REQUEST['change_prefs'] ) ) { foreach( $formFeatures as $item => $data ) { simple_set_toggle( $item, LIBERTY_PKG_NAME ); } - - $gBitSystem->storeConfig('liberty_cache', $_REQUEST['liberty_cache'] ); - $gBitSystem->storeConfig('liberty_auto_display_attachment_thumbs', $_REQUEST['liberty_auto_display_attachment_thumbs'] ); + simple_set_value('liberty_attachment_style', LIBERTY_PKG_NAME); + $gBitSystem->storeConfig('liberty_cache', $_REQUEST['liberty_cache'], LIBERTY_PKG_NAME ); + $gBitSystem->storeConfig('liberty_auto_display_attachment_thumbs', $_REQUEST['liberty_auto_display_attachment_thumbs'], LIBERTY_PKG_NAME ); if( $_REQUEST['approved_html_tags'] != DEFAULT_ACCEPTABLE_TAGS ) { $tags = preg_replace( '/\s/', '', $_REQUEST['approved_html_tags'] ); diff --git a/admin/schema_inc.php b/admin/schema_inc.php index c639c13..246f7d0 100644 --- a/admin/schema_inc.php +++ b/admin/schema_inc.php @@ -248,6 +248,7 @@ $gBitInstaller->registerPreferences( LIBERTY_PKG_NAME, array( // enable action logging by default array(LIBERTY_PKG_NAME, 'liberty_action_log', 'y'), // array(LIBERTY_PKG_NAME, 'liberty_attachment_link_format', 'wiki') not needed anymore since we use js in the edit page now (depends on format of content) +// array(LIBERTY_PKG_NAME, 'liberty_attachment_style', 'standard'), ) ); $gBitInstaller->registerSchemaDefault( LIBERTY_PKG_NAME, array( diff --git a/attachment_uploader.php b/attachment_uploader.php index 46a7950..e3a4835 100644 --- a/attachment_uploader.php +++ b/attachment_uploader.php @@ -1,6 +1,6 @@ <?php /** - * @version $Header: /cvsroot/bitweaver/_bit_liberty/attachment_uploader.php,v 1.2 2007/04/08 17:19:54 nickpalmer Exp $ + * @version $Header: /cvsroot/bitweaver/_bit_liberty/attachment_uploader.php,v 1.3 2007/04/16 14:03:13 nickpalmer Exp $ * @package liberty * @subpackage functions */ @@ -9,10 +9,42 @@ * required setup */ require_once( '../bit_setup_inc.php' ); -include (LIBERTY_PKG_PATH."LibertyAttachable.php"); -$la = new LibertyAttachable(); -if (!$la->storeAttachments($_REQUEST)) { - // Do something to indicate failure. +require_once(LIBERTY_PKG_PATH."LibertyAttachable.php"); +global $gBitSmarty, $gContent; + +$gContent = new LibertyAttachable(); + +if (!empty($_REQUEST['content_id'])) { + $gContent->mContentId = $_REQUEST['content_id']; } -// Do whatever you do on success + +if (isset($_FILES['upload'])) { + if (!$gContent->storeAttachments($_REQUEST, FALSE)) { + $gBitSmarty->assign('errors', $gContent->mErrors); + } + elseif (empty($gContent->mContentId)) { + // Fake it for preflight + $gContent->mStorage[$_REQUEST['attachment_id']] = $gContent->getAttachment($_REQUEST['attachment_id']); + } +} + +// load the attachments up +if (!empty($gContent->mContentId)) { + $gContent->load(); +} +elseif (!empty($_REQUEST['existing_attachment_id'])) { + // Fake it for preflight + foreach( $_REQUEST['existing_attachment_id'] as $id) { + $gContent->mStorage[$id] = $gContent->getAttachment($id); + } +} + +// Make them come out in the right order +ksort($gContent->mStorage); + +// Make the actions work +$gBitSmarty->assign('attachmentActionBaseURL', $_REQUEST['liberty_upload_action']); +$gBitSmarty->assign('gContent', $gContent); +$gBitSmarty->assign('libertyUploader', true); +echo $gBitSmarty->display('bitpackage:liberty/attachment_uploader.tpl'); ?> diff --git a/edit_storage_inc.php b/edit_storage_inc.php index 0f698d3..30a92f1 100644 --- a/edit_storage_inc.php +++ b/edit_storage_inc.php @@ -3,7 +3,7 @@ * edit_storage_inc * * @author spider <spider@steelsun.com> - * @version $Revision: 1.10 $ + * @version $Revision: 1.11 $ * @package liberty * @subpackage functions * @@ -13,21 +13,25 @@ * Calculate a base URL for the attachment deletion/removal icons to use */ global $gBitSmarty, $gContent, $gBitUser, $gBitSystem, $gLibertySystem; -$attachmentActionBaseURL = $_SERVER['PHP_SELF'].'?'; -$GETArgs = split('&',$_SERVER['QUERY_STRING']); -$firstArg = TRUE; -foreach( $GETArgs as $arg ) { - $parts = split('=',$arg); - if( ( $parts[0] != 'deleteAttachment' ) && $parts[0] != 'detachAttachment' ) { - if( !$firstArg ) - $attachmentActionBaseURL .= "&"; - else - $firstArg = FALSE; - $attachmentActionBaseURL .= $arg; +$attachmentActionBaseUrl = $gBitSmarty->get_template_vars('attachmentActionBaseURL'); +if( empty($attachmentActionBaseUrl) ) { + $attachmentActionBaseURL = $_SERVER['PHP_SELF'].'?'; + $GETArgs = split('&',$_SERVER['QUERY_STRING']); + $firstArg = TRUE; + + foreach( $GETArgs as $arg ) { + $parts = split('=',$arg); + if( ( $parts[0] != 'deleteAttachment' ) && $parts[0] != 'detachAttachment' ) { + if( !$firstArg ) + $attachmentActionBaseURL .= "&"; + else + $firstArg = FALSE; + $attachmentActionBaseURL .= $arg; + } } + $gBitSmarty->assign( 'attachmentActionBaseURL', $attachmentActionBaseURL ); } -$gBitSmarty->assign( 'attachmentActionBaseURL', $attachmentActionBaseURL ); if( !empty( $_REQUEST['deleteAttachment'] ) ) { $attachmentId = $_REQUEST['deleteAttachment']; @@ -55,5 +59,5 @@ $gBitSmarty->assign_by_ref( 'gLibertySystem', $gLibertySystem ); // seems like there should be a better way to do this -- maybe original assign should have been by reference? $gBitSmarty->clear_assign( 'gContent' ); $gBitSmarty->assign( 'gContent', $gContent ); - +$gBitSmarty->assign( 'loadAjax', TRUE ); ?> diff --git a/plugins/storage.bitfile.php b/plugins/storage.bitfile.php index 5c8e555..29a3741 100644 --- a/plugins/storage.bitfile.php +++ b/plugins/storage.bitfile.php @@ -1,6 +1,6 @@ <?php /** - * @version $Revision: 1.22 $ + * @version $Revision: 1.23 $ * @package liberty * @subpackage plugins_storage */ @@ -24,12 +24,12 @@ $pluginParams = array ( 'edit_help' => 'This file will be uploaded to your personal storage area.<br />After selecting the file you want to upload, please return to the edit area and click the save button.' ); -if ($gBitSystem->isFeatureActive("liberty_multiple_attachments")) { +if ($gBitSystem->getConfig("liberty_attachment_style") == "multiple") { $pluginParams['edit_label'] = 'Upload File(s)'; $pluginParams['edit_help'] = 'The file(s) will be uploaded to your personal storage area.<br />After selecting the file(s) you want to upload, please return to the edit area and click the save button.'; $pluginParams['edit_field'] = '<div id="upload_div"></div><input type="file" name="upload" size="40" id="uploads" /> <!-- Multiselect javascript. --> -<script> +<script type="text/javascript"> var upload_files = document.getElementById( \'upload_div\' ); var upload_element = document.getElementById( \'uploads\' ); var multi_selector = new MultiSelector( upload_files, '. @@ -39,6 +39,18 @@ if ($gBitSystem->isFeatureActive("liberty_multiple_attachments")) { </script>'; $gBitSmarty->assign( 'loadMultiFile', TRUE ); } +elseif ($gBitSystem->getConfig('liberty_attachment_style', "ajax") == "ajax") { + $divid = $gBitSmarty->get_template_vars('upload_div_id'); + if (empty($divid)) { + $divid = 0; + } + $pluginParams['edit_help'] = 'The file(s) will be uploaded to your personal storage area.<br />After selecting the file you want to upload an attachment ID will be displayed for you to use in your content.'; + $pluginParams['edit_field'] = ' +<input type="file" name="upload" size="40" id="upload" onchange="javascript:liberty_uploader(this, \'{$smarty.const.LIBERTY_PKG_URL}attachment_uploader.php\',\'{tr}Please wait for the current upload to finish.{/tr}\', \'liberty_upload_frame\', \'liberty_upload_action\');" /> +{include file="bitpackage:liberty/attachment_uploader_inc.tpl"} +'; + $gBitSmarty->assign( 'loadAjax', TRUE ); +} //$gLibertySystem->registerPlugin( STORAGE_TYPE_BIT_FILES, $pluginParams ); $gLibertySystem->registerPlugin( PLUGIN_GUID_BIT_FILES, $pluginParams ); diff --git a/templates/admin_liberty.tpl b/templates/admin_liberty.tpl index 8ce5785..cf054d8 100644 --- a/templates/admin_liberty.tpl +++ b/templates/admin_liberty.tpl @@ -11,6 +11,20 @@ </div> {/foreach} + {foreach from=$formLibertyAttachmentStyle key=item item=output} + <div class="row"> + {formlabel label=`$output.label` for=$item} + {forminput} + Current: {$gBitSystem->getConfig('liberty_attachment_style', 'standard')} + Item: {$item} + <input type="radio" name="liberty_attachment_style" value="{$item}" {if $gBitSystem->getConfig('liberty_attachment_style', 'standard') == $item}CHECKED{/if} /> + {formhelp note=`$output.note` page=`$output.page`} + {/forminput} + </div> + {/foreach} + + + <div class="row"> {formlabel label="Auto-Display Attachment Thumbnails" for="liberty_auto_display_attachment_thumbs"} {forminput} diff --git a/templates/attachment_uploader.tpl b/templates/attachment_uploader.tpl new file mode 100644 index 0000000..f0fb07e --- /dev/null +++ b/templates/attachment_uploader.tpl @@ -0,0 +1,23 @@ +{strip} +<html> +<head> +{include file="bitpackage:kernel/header_inc.tpl"} +</head> +<body> +{if !empty($errors)} + <script type="text/javascript"> + function display_upload_errors() {ldelim} + alert("Error with upload: {$errors}"); + {rdelim} + addLoadHook(display_upload_errors); + </script> +{/if} +{include file="bitpackage:liberty/edit_storage_list.tpl"} +{if empty($gContent->mContentId)} + {foreach from=$gContent->mStorage item=storage key=attachmentId} + <input type="hidden" name="existing_attachment_id[]" value="{$attachmentId}" /> + {/foreach} +{/if} +</body> +</html> +{/strip} diff --git a/templates/attachment_uploader_inc.tpl b/templates/attachment_uploader_inc.tpl new file mode 100644 index 0000000..81befd8 --- /dev/null +++ b/templates/attachment_uploader_inc.tpl @@ -0,0 +1,24 @@ +{strip} +<noscript> + {* the tr blocks are intentionally split so the second part only has to be translated once since it is duplicated in the iFrame. *} + <div class="warning"> + {tr}JavaScript is required for AJAX uploads.{/tr} + {tr}You must save the content to upload an attachment.{/tr} + </div> +</noscript> + +{* Ensure content_id is sent with the form if possible. *} +<input type="hidden" name="content_id" value="{$gContent->mContentId}" /> + +{* Give an input to stick the old action in*} +<input type="hidden" name="liberty_upload_action" value="" id="liberty_upload_action" /> + +{* Note! iFrame MUST not be display: none or Safari pops a window instead. *} +{* I am not dynamically creating the iFrame to give a warning for browsers with no iframe support. *} +<iframe src="about:blank" id="liberty_upload_frame" name="liberty_upload_frame" onload="javascript:liberty_uploader_complete('liberty_upload_frame', 'edit_storage_list_div', 'upload');" style="position: absolute; left: -10000px;"> + <div class="warning"> + {tr}iFrame support is required for AJAX uploads.{/tr} + {tr}You must save the content to upload an attachment.{/tr} + </div> +</iframe> +{/strip} diff --git a/templates/edit_storage.tpl b/templates/edit_storage.tpl index cc63ad8..c4e25d5 100644 --- a/templates/edit_storage.tpl +++ b/templates/edit_storage.tpl @@ -14,7 +14,9 @@ {/if} {/foreach} +<div id="edit_storage_list_div"> {include file="bitpackage:liberty/edit_storage_list.tpl"} +</div> <h2 class="clear"><a href="javascript:ajax_updater( 'attbrowser', '{$smarty.const.LIBERTY_PKG_URL}ajax_attachment_browser.php', 'ajax=true' );">{tr}Attachment Browser{/tr}</a></h2> <noscript><div class="warning">{tr}The attachment browser only works with javascript enabled.{/tr}</div></noscript> diff --git a/templates/edit_storage_list.tpl b/templates/edit_storage_list.tpl index 6713c01..1055a13 100644 --- a/templates/edit_storage_list.tpl +++ b/templates/edit_storage_list.tpl @@ -3,7 +3,7 @@ {if $gContent->mStorage} <div class="row"> <table class="data" summary="List of attached files"> - <caption>{tr}Items Attached Directly to this Content{/tr}</caption> + <caption>{tr}Items {if $libertyUploader && empty($gContent->mContentId)}That Will Be{/if} Attached Directly to this Content{/tr}</caption> <tr> <th scope="col" title="{tr}Thumbnail{/tr}">{tr}Thumbnail{/tr}</th> <th scope="col" title="{tr}File Properties{/tr}">{tr}File Properties{/tr}</th> @@ -20,9 +20,9 @@ Actions: {if $gBitUser->isAdmin() || $gBitUser->hasPermission( 'p_liberty_detach_attachment' ) || $storage.user_id == $gBitUser->mUserId} {if isset($gContent) } - <a href="{$attachmentActionBaseURL}&content_id={$gContent->mContentId}&detachAttachment={$attachmentId}">{biticon ipackage=liberty iname="detach" iexplain="detach"}</a> + <a href="{$attachmentActionBaseURL}&content_id={$gContent->mContentId}&detachAttachment={$attachmentId}">{biticon ipackage=icons iname="edit-cut" iexplain="detach"}</a> {else} - <a href="{$attachmentActionBaseURL}&detachAttachment={$attachmentId}">{biticon ipackage=liberty iname="detach" iexplain="detach"}</a> + <a href="{$attachmentActionBaseURL}&detachAttachment={$attachmentId}">{biticon ipackage=icons iname="edit-cut" iexplain="detach"}</a> {/if} {/if} {if $gBitUser->isAdmin() || $storage.user_id == $gBitUser->mUserId} |
