Browse Source

Merge pull request #1174 from tripal/1122-tv3-permanent_files

Permanent Files
Stephen Ficklin 3 years ago
parent
commit
0be583c516

+ 17 - 0
docs/user_guide/file_management.rst

@@ -17,3 +17,20 @@ In addition to the default settings for all users, you may want to allow specifi
 Here you must specify the Drupal user name of the user who should be granted a custom quota.  This field will auto populate suggestions as you type to help you find the correct username.  Enter the desired quota size and expiration days and click the **Submit** button. you will then see the user-specific quota listed in the table at the bottom of the page:
 
 .. image:: ./file_management.user_quotas.3.png
+
+User's Files
+------------
+User's with permission to upload files are able to use the Tripal file uploader to add files to the server.  The core Tripal Data Importers use the Tripal file uploader and extension modules may use it as well.  You can enable this functionality for users by Navigating to **Admin** > **People** and click the **Permissions** Tab. next scrol to the **Tripal** section and set the **Upload Files** permissions as desired for your site.  The following screenshot shows the permission on a default Drupal site.
+
+
+.. image:: ./file_upload_permission.png.png
+
+User's who have the ability to upload files can manage files on their own Account pages.  
+
+As described in the previous section, the site administrator can set a system-wide or user-specific default expiration number of days for a file. This means files will be removed automatically from the server once their expiration data is set.
+
+.. note::
+
+  Automatic removal of files can only occur if the Drupal cron is setup to run automatically.
+  
+Each  

BIN
docs/user_guide/file_upload_permission.png


+ 25 - 4
tripal/api/tripal.quotas.api.inc

@@ -88,6 +88,12 @@ function tripal_expire_files(TripalJob $job = NULL) {
     ->fields('tgfe')
     ->execute();
   while ($result = $results->fetchObject()) {
+    // Skip files that have an expiration date of -1.  These are files
+    // that should be permenant.
+    if ($result->expiration_date == -1) {
+      continue;
+    }
+    // For files that have exceeded the expiration date, remove those.
     if (time() > $result->expiration_date) {
 
       $file = file_load($result->fid);
@@ -112,17 +118,32 @@ function tripal_expire_files(TripalJob $job = NULL) {
  *
  * @param $fid
  *   The file ID of the file to reset.
+ * @param $is_permanent
+ *   Set to TRUE if this file should be marked to never expire.
+ * @param $days
+ *   Manually set a number of days until expirtaion. If this is NULL then
+ *   the default setting is used.
  *
  * @return
  *   The new expiration date on success, FALSE on failure.
  */
-function tripal_reset_file_expiration($fid) {
+function tripal_reset_file_expiration($fid, $is_permanent=FALSE, $days=NULL) {
 
   $file = file_load($fid);
   try {
-    $quota = tripal_get_user_quota($file->uid);
-    $custom_expiration = $quota->custom_expiration;
-    $expiration_date = time() + $custom_expiration * 24 * 60 * 60;
+    if ($is_permanent===TRUE) {
+      $expiration_date = -1;
+    }
+    else {
+      $quota = tripal_get_user_quota($file->uid);
+      $custom_expiration = $quota->custom_expiration;
+      if (is_integer($days)) {
+        $expiration_date = time() + $days * 24 * 60 * 60;
+      }
+      else {
+        $expiration_date = time() + $custom_expiration * 24 * 60 * 60;
+      }
+    }
 
     db_delete('tripal_expiration_files')
       ->condition('fid', $fid)

+ 89 - 41
tripal/includes/tripal.user.inc

@@ -81,8 +81,8 @@ function tripal_user_get_files_item_list($files_list, &$i = 0) {
   if ($i == 0) {
     $items[] = [
       'data' => '<span><b>File</b></span>' .
-        '<span class="file-expires"><b>Expires</b></span>' .
-        '<span class="file-size"><b>Size</b></span>',
+        '<span class="tripal-user-file-expires tripal-user-file-browser-header"><b>Expires</b></span>' .
+        '<span class="tripal-user-file-size tripal-user-file-browser-header"><b>Size</b></span>',
     ];
   }
 
@@ -95,25 +95,31 @@ function tripal_user_get_files_item_list($files_list, &$i = 0) {
         'data' => $filename,
         'children' => tripal_user_get_files_item_list($file, $i),
         'class' => [
-          'tree-node-folder',
-          'tree-node-closed',
+          'tripal-user-tree-node-folder',
+          'tripal-user-tree-node-closed',
           ($i % 2 == 0) ? 'even' : 'odd',
         ],
       ];
     }
     // If this is a file then give details for it.
     else {
-      $datediff = $file->expiration_date - time();
-      $dayleft = round($datediff / (60 * 60 * 24));
-      if ($dayleft < 0) {
-        $dayleft = 0;
+      if ($file->expiration_date == -1) {
+        $daysleft = 'Never';
+      }
+      else {
+        $datediff = $file->expiration_date - time();
+        $daysleft = round($datediff / (60 * 60 * 24));
+        if ($daysleft < 0) {
+          $daysleft = 0;
+        }
+        $expiration = $file->expiration_date ? date('Y-m-d', $file->expiration_date) : '';
+        $daysleft = $daysleft . ' days';
       }
-      $expiration = $file->expiration_date ? date('Y-m-d', $file->expiration_date) : '';
       $items[] = [
-        'data' => '<span class="file-details"><span class="file-name">' . $filename . '</span>' .
-          '<span class="file-expires">' . $dayleft . ' days</span>' .
-          '<span class="file-size">' . tripal_format_bytes($file->filesize) . '</span></span>',
-        'class' => ['tree-node-file', ($i % 2 == 0) ? 'even' : 'odd'],
+        'data' => '<span class="tripal-user-file-details"><span class="tripal-user-file-name">' . $filename . '</span>' .
+          '<span class="tripal-user-file-expires">' . $daysleft . '</span>' .
+          '<span class="tripal-user-file-size">' . tripal_format_bytes($file->filesize) . '</span></span>',
+        'class' => ['tripal-user-tree-node-file', ($i % 2 == 0) ? 'even' : 'odd'],
         'fid' => $file->fid,
         'uid' => $file->uid,
       ];
@@ -216,32 +222,40 @@ function tripal_user_files_page($uid) {
   $quota = tripal_get_user_quota($uid);
   $usage = tripal_get_user_usage($uid);
 
+  drupal_add_library('system', 'drupal.collapse');
   $content = [
     'page_title' => [
       '#type' => 'markup',
       '#markup' => '<h2>Your Files</h2>',
     ],
-    'page_description' => [
-      '#type' => 'markup',
-      '#markup' => '<p>' . t('Each user is allowed to consume a limited amount of space for files. This page provides details about your current usage, your limits and files in your account.') . '</p>',
-    ],
-    'usage' => [
-      '#type' => 'item',
-      '#title' => 'Current Usage',
-      '#markup' => tripal_format_bytes($usage),
-      '#description' => t('The total number of bytes you currently consume.'),
-    ],
-    'quota' => [
-      '#type' => 'item',
-      '#title' => 'Current Quota',
-      '#markup' => tripal_format_bytes($quota->custom_quota),
-      '#description' => t('The maximum number of bytes of files you can upload.'),
-    ],
-    'expiration' => [
-      '#type' => 'item',
-      '#title' => 'Current Days to Expire',
-      '#markup' => $quota->custom_expiration,
-      '#description' => t('The number of days a file will remain on the server before deletion. The expiration of date of a file can be renewed by selecting the file name and then selecting the "Renew" link in the file details table.'),
+    'limits' => [
+      '#type' => 'fieldset',
+      '#title' => 'Usage and Limits',
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+      '#attributes' => ['class' => ['collapsible', 'collapsed']],
+      'page_description' => [
+        '#type' => 'markup',
+        '#markup' => '<p>' . t('Each user is allowed to consume a limited amount of space for files. This page provides details about your current usage, your limits and files in your account.') . '</p>',
+      ],
+      'usage' => [
+        '#type' => 'item',
+        '#title' => 'Current Usage',
+        '#markup' => tripal_format_bytes($usage),
+        '#description' => t('The total number of bytes you currently consume.'),
+      ],
+      'quota' => [
+        '#type' => 'item',
+        '#title' => 'Current Quota',
+        '#markup' => tripal_format_bytes($quota->custom_quota),
+        '#description' => t('The maximum number of bytes of files you can upload.'),
+      ],
+      'expiration' => [
+        '#type' => 'item',
+        '#title' => 'Current Days to Expire',
+        '#markup' => $quota->custom_expiration,
+        '#description' => t('The number of days a file will remain on the server before deletion. The expiration of date of a file can be renewed by selecting the file name and then selecting the "Renew" link in the file details table.'),
+      ],
     ],
     'data_collections' => [
       '#type' => 'item',
@@ -256,11 +270,15 @@ function tripal_user_files_page($uid) {
       '#type' => 'item',
       '#title' => 'File Browser',
       '#markup' => $theme_files,
+      '#prefix' => '<div id="tripal-user-file-browser">',
+      '#suffix' => '</div>',
     ],
     'file_details' => [
       '#type' => 'item',
       '#title' => 'File Details',
-      '#markup' => '<div id="tripal-user-file-details">Click a file above for details.</div>',
+      '#markup' => 'Click a file name for details.',
+      '#prefix' => '<div id="tripal-user-file-details">',
+      '#suffix' => '</div>',
     ],
   ];
 
@@ -288,7 +306,24 @@ function tripal_renew_file($fid) {
   $success = tripal_reset_file_expiration($fid);
 
   if ($success) {
-    drupal_set_message('Successfully updated expiration date.');
+    drupal_set_message(t('The expiration date for the file, \'!fname\', is now reset.', ['!fname' => $file->filename]));
+  }
+  drupal_goto('user/' . $file->uid . '/files/');
+}
+
+/**
+ * User action to remove the expiration of a file.
+ *
+ * Sets the expriation date to a -1 value indicating that the file
+ * should not be automatically removed.
+ *
+ **/
+function tripal_set_file_permanent($fid) {
+  $file = file_load($fid);
+  $success = tripal_reset_file_expiration($fid, TRUE);
+
+  if ($success) {
+    drupal_set_message(t('The file, \'!fname\', is now permanent.', ['!fname' => $file->filename]));
   }
   drupal_goto('user/' . $file->uid . '/files/');
 }
@@ -430,10 +465,6 @@ function tripal_view_file($uid, $fid) {
   $headers = [];
   $rows = [];
 
-  $actions = l('Delete', "user/$uid/files/$file->fid/delete") . '<br>' .
-    l('Download', "user/$uid/files/$file->fid/download") . '<br>' .
-    l('Renew', "user/$uid/files/$file->fid/renew");
-
   // Name row
   $rows[] = [
     [
@@ -459,7 +490,12 @@ function tripal_view_file($uid, $fid) {
     ->condition('fid', $fid)
     ->execute()
     ->fetchField();
-  $expiration = $expiration_date ? date('Y-m-d H:i:s', $expiration_date) : '';
+  if ($expiration_date == -1) {
+    $expiration = 'Never';
+  }
+  else {
+    $expiration = $expiration_date ? date('Y-m-d H:i:s', $expiration_date) : '';
+  }
   $rows[] = [
     [
       'data' => 'Expiration Date',
@@ -480,6 +516,17 @@ function tripal_view_file($uid, $fid) {
       file_get_contents($md5_file),
     ];
   }
+
+
+  $actions = l('Delete', "user/$uid/files/$file->fid/delete") . '<br>' .
+    l('Download', "user/$uid/files/$file->fid/download") . '<br>' .
+    l('Renew Expiration', "user/$uid/files/$file->fid/renew") . '<br>';
+
+  if (user_access('make files permanent')) {
+    if ($expiration_date != -1) {
+      $actions .= l('Make Permanent', "user/$uid/files/$file->fid/permanent");
+    }
+  }
   $rows[] = [
     [
       'data' => 'Actions',
@@ -489,6 +536,7 @@ function tripal_view_file($uid, $fid) {
     $actions,
   ];
 
+
   $file_content = theme_table([
     'header' => $headers,
     'rows' => $rows,

+ 12 - 12
tripal/theme/css/tripal_user_files.css

@@ -1,16 +1,20 @@
+#tripal-user-file-browser {
+}
+#tripal-user-file-details {
+}
 #tripal-user-file-tree {
   margin: 0;
   padding: 10px;
-  height: 250px;
+  max-height: 250px;
   overflow: auto;
   border: 1px solid #AAAAAA;
 }
-#tripal-user-file-tree li.tree-node-folder {
+#tripal-user-file-tree li.tripal-user-tree-node-folder {
   background: url(../images/directory.png) no-repeat;
   background-size: 22px 22px;
   cursor: pointer;
 }
-#tripal-user-file-tree li.tree-node-file {
+#tripal-user-file-tree li.tripal-user-tree-node-file {
   background: url(../images/txt.png) no-repeat;
   background-size: 22px 22px;
   cursor: pointer;
@@ -26,31 +30,27 @@
   padding: 0;
 }
 #tripal-user-file-tree li {
-	list-style-type: none;
+  list-style-type: none;
   margin: 0px;
   padding: 0px 0px 0px 30px;
   line-height: 22px;
 }
-#tripal-user-file-tree .file-name {
-  color: #369;	
+#tripal-user-file-tree .tripal-user-file-name {
 }
-#tripal-user-file-tree .file-size {
+#tripal-user-file-tree .tripal-user-file-size {
   float: right; 
   padding-left: 10px;
   font-size: 0.8em; 
-  width: 60px;
   text-align: right;
 }
-#tripal-user-file-tree .file-expires {
+#tripal-user-file-tree .tripal-user-file-expires {
   float: right; 
   padding-left: 10px;
   font-size: 0.8em; 
-  width: 60px;
   text-align: right;
 }
 #tripal-user-file-tree a {
   border-bottom-width: 1px;
   border-bottom-style: dotted;
 }
-#tripal-user-file-details {
-}
+

+ 9 - 9
tripal/theme/js/tripal.user_files.js

@@ -9,17 +9,17 @@
       $('#tripal-user-file-tree ul').removeAttr('class');
       
       // Set default actions for closed and open folders.
-      $('.tree-node-closed').children().hide();
-      $('.tree-node-closed').click(function(event) {
+      $('.tripal-user-tree-node-closed').children().hide();
+      $('.tripal-user-tree-node-closed').click(function(event) {
         expandNode($(this));
       });
-      $('.tree-node-open').click(function(event) {
+      $('.tripal-user-tree-node-open').click(function(event) {
         collapseNode($(this));
       });
       
       // Keep clicks on the files from propagating up to folders and
       // causing collapse.
-      $('.tree-node-file').click(function(event) {
+      $('.tripal-user-tree-node-file').click(function(event) {
       	event.stopPropagation();
       	
       	// Reset the colors for all of the elements.
@@ -30,7 +30,7 @@
       	showFileDetails($(this));
       	
       	// Higlight the selected file.
-      	$(this).css("background-color", "#FFAAAA");
+      	$(this).css("background-color", "#CCCCCC");
       });
     }
   }
@@ -53,8 +53,8 @@
    * Collapses a node in the CV tree browser and removes its children.
    */
   function collapseNode(item) {
-    item.removeClass('tree-node-open');
-    item.addClass('tree-node-closed');
+    item.removeClass('tripal-user-tree-node-open');
+    item.addClass('tripal-user-tree-node-closed');
     item.children().hide()
     item.unbind('click');
     item.click(function(event){
@@ -66,8 +66,8 @@
    * Expands a node in the CV tree browser and loads it's children via AJAX.
    */
   function expandNode(item){
-    item.removeClass('tree-node-closed');
-    item.addClass('tree-node-open');
+    item.removeClass('tripal-user-tree-node-closed');
+    item.addClass('tripal-user-tree-node-open');
     item.children().show()
     item.unbind('click');
     item.click(function(event){

+ 18 - 1
tripal/tripal.module

@@ -573,7 +573,7 @@ function tripal_menu() {
 
   // User file renew.
   $items['user/%/files/%/renew'] = [
-    'title' => 'Renew File',
+    'title' => 'Renew File Expiration',
     'description' => "Renew a user's file",
     'page callback' => 'tripal_renew_file',
     'page arguments' => [3],
@@ -583,6 +583,17 @@ function tripal_menu() {
     'file' => 'includes/tripal.user.inc',
     'file path' => drupal_get_path('module', 'tripal'),
   ];
+  $items['user/%/files/%/permanent'] = [
+    'title' => 'Make File Permanent',
+    'description' => "Removes the expiration date of a file. It will never be removed.",
+    'page callback' => 'tripal_set_file_permanent',
+    'page arguments' => [3, TRUE],
+    'access callback' => 'tripal_access_user_files',
+    'access arguments' => ['renew', 1, 3],
+    'type' => MENU_CALLBACK,
+    'file' => 'includes/tripal.user.inc',
+    'file path' => drupal_get_path('module', 'tripal'),
+  ];
   // User file download.
   $items['user/%/files/%/download'] = [
     'title' => 'Download File',
@@ -736,6 +747,12 @@ function tripal_permission() {
       'title' => t('Upload Files'),
       'description' => t('Allows the user to upload files using Tripal\'s HTML5 loader.'),
     ),
+    'make files permanent' => array(
+      'title' => t('Make Files Permanent'),
+      'description' => t('Allows the user to make files they have access to ' .
+         'permanent. Files that are permanent will not expire and will not ' .
+         'be cleaned up.'),
+    ),
     'view dev helps' => array(
       'title' => t('View Developer Hints'),
       'description' => t('Tripal will provide blue shaded boxes that provide