We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 29774
    • 386 Posts
    A simple snippet to grab the file size, date modified and file icon for a given file. I have used it to generate a list of files by using it in a NewsListing (Ditto) template, where the filepath is passed as a TV to the newslisting template (each document being listed has a TV called ’file’):

    Example use in a NewsListing template (we’re outputting items inside a <dl>):

    <dt><a href="[+tvfile+]">[+title+]</a></dt>
    <dd>
    [+summary+]
    [!FileDetails?file=`[+tvfile+]`!]
    </dd>
    


    Real life example:
    http://www.aquavision.co.uk/documentation

    I believe this is preferable to to uploading documents to a directory and just listing the directory, because you can use the document to describe the file meta data, and also files can be searched, ordered and listed like any other document. And it makes a lot more sense to see the files in the document tree.

    I have attached a folder of icons called ’fileicons’ - copy this folder to /assets/images/.

    Incidently, I have used the file extension to determine the file type; a better option would be to use the Mime type, but I decided this would require too much overhead. If anyone knows of a clean and simple way to determine mimetype please let me know!

    /*
       Snippet Name: FileDetails
       Short Desc: Returns file information for supplied file path (size, date modified, file icon).
       Created By: [email protected]
       Last modified: 26/06/2006
       Version: 1.0
    
       Example call: [!FileDetails?file=`/assets/myfile.pdf` &tpl=`chunkName` &icondir=`/assets/fileicons/`!]
    
       Note: The parameter file is required or you will recieve no results.
    
       Params:
        &file  = file path to use (must be a root relative path) (string)
        &tpl = Chunk name to use for formatting file details (string)
        &icondir = path to the file icons directory (root relative or absolute path) (string)
        &iconsize = "small" | "standard" (string)
        $dtformat = date format (string)
        &bytemode = "SI"|"IEC" [Metric where 1 Kb=1000 bytes or IEC where 1 Kb=1024 bytes] (string)
        &digits =  number of digits for the file size (integer)
    */
    
    /* Globals */
    global $base_path;
    global $site_url;
    
    /* Parameters */
    $file = isset($file)? "$file" : '';
    $tpl = isset($tpl)? "$tpl" : '[+icon+] [+size+] | [+filedate+]';
    $icondir = isset($icondir)? "$icondir" : $site_url.'assets/images/fileicons/';
    $iconsize = isset($iconsize)? "$iconsize" : 'small';
    $dtformat = isset($dtformat)? "$dtformat" : 'F d Y';
    $bytemode = isset($bytemode)? "$bytemode" : 'SI';
    $digits = isset($digits)? "$digits" : '3';
    
    $file =  $base_path.(substr_replace($file, '', 0,1));
    
    $output = '';
    
    if ($file != "") {	
    	
    	# grab file details
    	$file = getFileDetails($file, $icondir, $dtformat, $digits, $bytemode, $iconsize);
    	
    	# map to template
    	$tpl = $modx->getChunk($tpl);
    	$fields = array('[+size+]', '[+icon+]', '[+filedate+]');
    	$values = array($file['size'],$file['icon'],$file['date']);
    	$output .= str_replace($fields,$values,$tpl);
    }
    return $output;
    
    /* ---------------------------------------------------
       Functions
       --------------------------------------------------- */
    
    /* courtesy of [email protected] */
    function formatbytes($val, $digits = 3, $mode = "SI", $bB = "B"){ //$mode == "SI"|"IEC", $bB == "b"|"B"
           $si = array("", "k", "M", "G", "T", "P", "E", "Z", "Y");
           $iec = array("", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi");
           switch(strtoupper($mode)) {
               case "SI" : $factor = 1000; $symbols = $si; break;
               case "IEC" : $factor = 1024; $symbols = $iec; break;
               default : $factor = 1000; $symbols = $si; break;
           }
           switch($bB) {
               case "b" : $val *= 8; break;
               default : $bB = "B"; break;
           }
           for($i=0;$i<count($symbols)-1 && $val>=$factor;$i++)
               $val /= $factor;
           $p = strpos($val, ".");
           if($p !== false && $p > $digits) $val = round($val);
           elseif($p !== false) $val = round($val, $digits-$p);
           return round($val, $digits) . " " . $symbols[$i] . $bB;
       }
       
    # Outputs image link dependant of passed in mime type.
    function getFileIcon($ext, $icondir, $iconsize="normal") {
    
    	# Determine if we need small or standard sizes file icons
    	if ($iconsize === "small") {
    		$suffix = "_s.gif";
    	} else {
    		$suffix = ".gif";
    	}
    
    	$ext = strtolower($ext);
    	
    	# Case statement based around extension type:
    	switch($ext) {
    		#IMAGES:
    		case 'gif': case 'jpg': case 'jpeg': case 'png': case 'tif': case 'tiff':  case 'bmp':
    			$icon = 'icon_image'.$suffix;
    			$alt = 'Image';
    			break;
    		#EXCEL:
    		case 'xls':
    			$icon = 'icon_excel'.$suffix;
    			$alt = 'Microsoft Excel';
    			break;
    		#HTML:
    		case 'html': case 'htm':
    			$icon = 'icon_html'.$suffix;
    			$alt = 'HTML';
    			break;
    		#PDF:
    		case 'pdf':
    			$icon = 'icon_pdf'.$suffix;
    			$alt = 'Adobe PDF';
    			break;
    		#POWERPOINT:
    		case 'ppt':
    			$icon = 'icon_pp'.$suffix;
    			$alt = 'Microsoft Powerpoint';
    			break;
    		#TEXT
    		case 'rtf': case 'txt': case 'css': case 'js': case 'xml':
    			$icon = 'icon_text'.$suffix;
    			$alt = 'Text';
    			break;
    		#WORD
    		case 'doc':
    			$icon = 'icon_word'.$suffix;
    			$alt = 'Microsoft Word';
    			break;
    		#DEFAULT
    		default:
    			$icon = 'icon_generic'.$suffix;
    			$alt = 'Generic';
    			break;
    	}
    		
    	$imageUrl  = '<img src="'.$icondir.$icon.'" alt="'.$alt.'" title="'.$alt.'" />';
    	return $imageUrl;
    }   
    
    function getFileDetails ($filepath, $icondir, $dtformat, $digits, $bytemode, $iconsize) {
    	
    	$file = array();
    	
    	If (is_file($filepath)) {
    		
    		// get file size
    		$file['size'] = formatbytes(filesize($filepath), $digits, $bytemode, "B");
    		
    		//get path info
    		$pathinfo = pathinfo($filepath);
    		
    		// get file extension
    		$file_ext = $pathinfo['extension'];
    	
    		//get file icon
    		$file['icon'] = getFileIcon($file_ext, $icondir, $iconsize);
    	
    		//get file date last modified
    		$file['date'] = date ($dtformat, filemtime($filepath));
    	}
    	return $file;
    }
    
      Snippets: GoogleMap | FileDetails | Related Plugin: SSL
      • 6726
      • 7,075 Posts
      Interresting alternative to FileDownload, I might just have a use for this smiley

      Thanks a lot ! I’ll try this one out and report !
        .: COO - Commerce Guys - Community Driven Innovation :.


        MODx est l&#39;outil id
        • 33175
        • 711 Posts
        Excellent !

        I will use it !! smiley
          Sorry for my english. I&#39;m french... My dictionary is near me, but it&#39;s only a dictionary !
          • 6726
          • 7,075 Posts
          Initially, I didn’t quite get that FileDetails did not recursively list all files in a folder, but just file details of a specificied file.
          I was (am) interrested in having both Metadata, description field AND the ability to list a directory... maybe combine the two snippets, I don’t know.

          Anyway, this mean it will be most useful for permanent download link, and can not be used to handle a download section (unless I am mistaken here...).
            .: COO - Commerce Guys - Community Driven Innovation :.


            MODx est l&#39;outil id
            • 29774
            • 386 Posts
            Hi David, the idea with FileDetails is that you use a document to represent a file. The document can have any number of tvs to store meta data about the file, and you can order it and search it like any other document. I use a template called ’file download’ for my files which has the tvs I want, including a tv called ’file’; the template contains a snippet call like this: [!sendRedirect?url=`[*file*]`!]

            sendRedirect in turn is a tiny snippet:
            $url = isset($url)? "$url" : '';
            return $modx->sendRedirect($url);
            


            This means that if the document is linked to directly (say in a site map, menu or search results), then the browser is redirected to the file.

            Finally, you can use Ditto to iterate through the documents in a folder, and use FileDetails in the Ditto template to grab the data for each file. This way we’re leveraging the features of Ditto instead of recreating what it does best.

            One interesting possibility of this arrangement would be to restrict access to files just by creating document groups and assigning access to user groups. To be properly secure, the ’file’ tv would need to upload files to a custom db table rather than store them in the filesystem. (There is a method for storing even very large files in db tables by splitting the data into chunks that are stored in incremental rows). But that would require a custom input type for the tv (not possible at the moment without hacking the manager afaik), or a module to handle it. Anyway, that might be an approach for managing access to files in an extranet for example.
              Snippets: GoogleMap | FileDetails | Related Plugin: SSL
              • 6726
              • 7,075 Posts
              Very smart therebechips !

              Thanks for taking the time to enlighten me, I like the idea very much smiley
                .: COO - Commerce Guys - Community Driven Innovation :.


                MODx est l&#39;outil id
                • 18397
                • 3,250 Posts
                Could you add this to our new file repository (if it isn’t already there) at http://www.modxcms.com/downloads.html
                  • 13736
                  • 345 Posts
                  Maybe I’m too dumb to link all the necessary steps together. But is there any sort of tutorial for getting this to work in Ditto like described above?

                  I’m needing some way to upload a file to a folder from the front end (webuser accounts) and have them automaticly list on the page. But also provide a short description or comment for those files during the upload process.

                  <rant>
                  I think MODx is starting to become to complex compared to what initialy attracted me back in Version 0.9.2. Instead of getting more streamlined or simplified it’s becoming like a spider web to get anything done. I would much rather have a single file management snippet that handled the upload and display all in one (including the comments and details).
                  </rant>

                  Perhaps we need more official MODx tutorials on the main site for some of the more complicated real world uses (like this one).
                    • 28042 ☆ A M B ☆
                    • 24,524 Posts
                    MODx is just as easy to work with as it ever was. It’s just that everyone wants it to do something else, and that means additional snippets and modules. It’s like saying that Linux has gotten too complex because users want to have media players, web browsers, mail and calendaring clients and office applications.

                    If you go to the Resources page and take a look at the tag cloud for "file management" you should find what you are looking for. Although I’ve been thinking about this ever since I saw it...
                    http://digitarald.de/project/fancyupload/
                      Studying MODX in the desert - http://sottwell.com
                      Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
                      Join the Slack Community - http://modx.org
                      • 21112
                      • 156 Posts
                      Is it possible to choose which file details are displayed by this snippet? I want to format the location of the icon and filesize and I don’t want to display the date. I’m using this in a ditto template, and I’d like to have the ocon on the left, the filename (from ditto) in the middle and the file size to the right.

                      Would it be possible to modify the snippet to allow something like the following?

                      [!FileDetails?file=`/assets/myfile.pdf` &filesize=`1` &fileicon=`1` &filedata=`0`!]

                      I could then reuse the chunk throughout the ditto template, only turning on the output that I want in each use.