| Current Path : /home/purehotels/public_html/components/com_easyfolderlistingpro/helpers/ |
| Current File : /home/purehotels/public_html/components/com_easyfolderlistingpro/helpers/EFLPListing.Class.php |
<?php
/**
* @name EFLPListing
* @description
* @author Michael Gilkes (Valor Apps)
* @created Monday, March 24, 2014
* @modified
* @version 1.6
* @copyright Copyright (C) 2012-2016 Michael Albert Gilkes. All rights reserved.
* @license GNU General Public License version 3 or later; see LICENSE
*/
/*
[08-May-2012 13:19:19] JPATH_ADMINISTRATOR=/Applications/MAMP/htdocs/Joomla_2.5/administrator
[08-May-2012 13:19:19] JPATH_BASE=/Applications/MAMP/htdocs/Joomla_2.5
[08-May-2012 13:19:19] JPATH_CACHE=/Applications/MAMP/htdocs/Joomla_2.5/cache
[08-May-2012 13:19:19] JPATH_COMPONENT=/Applications/MAMP/htdocs/Joomla_2.5/components/com_advlisting
[08-May-2012 13:19:19] JPATH_COMPONENT_ADMINISTRATOR=/Applications/MAMP/htdocs/Joomla_2.5/administrator/components/com_advlisting
[08-May-2012 13:19:19] JPATH_COMPONENT_SITE=/Applications/MAMP/htdocs/Joomla_2.5/components/com_advlisting
[08-May-2012 13:19:19] JPATH_CONFIGURATION=/Applications/MAMP/htdocs/Joomla_2.5
[08-May-2012 13:19:19] JPATH_INSTALLATION=/Applications/MAMP/htdocs/Joomla_2.5/installation
[08-May-2012 13:19:19] JPATH_LIBRARIES=/Applications/MAMP/htdocs/Joomla_2.5/libraries
[08-May-2012 13:19:19] JPATH_PLUGINS=/Applications/MAMP/htdocs/Joomla_2.5/plugins
[08-May-2012 13:19:19] JPATH_ROOT=/Applications/MAMP/htdocs/Joomla_2.5
[08-May-2012 13:19:19] JPATH_SITE=/Applications/MAMP/htdocs/Joomla_2.5
[08-May-2012 13:19:19] JPATH_THEMES=/Applications/MAMP/htdocs/Joomla_2.5/templates
*/
defined('JPATH_PLATFORM') or die;
require_once("ValorUtilities.Class.php");
require_once("MultiDownload.Class.php");
//imports
jimport('joomla.filesystem.file');
jimport('joomla.environment.uri');
jimport('joomla.utilities.string');
abstract class EFLPListing extends JObject
{
const CLASS_PREFIX = 'eflpro_';
const INVALID_EXTS = 'php,htm,html,asp,aspx';
const GOOGLE_PREVIEW_EXTS = 'doc,docx,xls,xlsx,ppt,pptx,pdf,pages,ai,psd,tiff,dxf,svg,eps,ps,ttf,xps,zip,rar,gif,png,jpeg,jpg,bmp';
const BROWSER_PREVIEW_EXTS = 'pdf,gif,png,jpeg,jpg,bmp,mp3';
const MODAL_ID = 'eflpModal';
const MODAL_JQY = 'eflp_modal_jqy';
const MODAL_MOO = 'eflp_modal_moo';
protected $listingId;
protected $files;
protected $folders;
protected $config;
protected $iconsdata;
protected $expires = 0;
protected $mootools = true;
protected $headings = array();
protected $serializedParameters;
protected $username;
protected $userId;
protected $isInJoomlaRoot = false;
/**
* Constructor used to initialize the parameters, config, files
*/
public function __construct($id, $parameters = null, $config = null, $icons = null, $files = null, $folders = null)
{
//assign the pre-contructed id for listing
$this->listingId = $id;
//assign the pre-processed files data. already sorted.
$this->files = $files;
//set whether location path is in the Joomla root
$this->isInJoomlaRoot = ValorUtilities::isInJoomlaRoot($parameters['folder']);
//set when links will expire
if ($parameters['limitlink'])
{
//timelimit is in minutes. need to convert to seconds
$timelimit = intval($parameters['timelimit']);
$this->expires = time() + ($timelimit * 60);
}
//assign the pre-processed folders data. already sorted.
$this->folders = $folders;
//component configuration parameters
$this->config = $config;
//component icons data
$this->iconsdata = $icons;
//serialize and obfucate the parameters
$this->serializedParameters = ValorUtilities::obfuscate($parameters);
//save the username from the start
$user = JFactory::getUser();
if ($user->guest == false)
{
$this->username = $user->username;
}
else
{
$this->username = '';
}
//save the user id
$this->userId = $user->id;
parent::__construct($parameters);
//setup the custom javascript
$this->setupJavascript();
}
/**
* Sets up the javscript framework flag
*/
protected function setupJavascript()
{
$framework = $this->get('javascript');
if ($framework == 'mootools')
{
$this->mootools = true;
}
else //$framework == 'jquery'
{
$this->mootools = false;
}
}
/**
* Inherited function used to render the HTML
*/
public abstract function renderHTML();
/**
*
*/
protected function addSearchPanel($textLength = 2)
{
$html = '';
$esc = ($this->get('escfilter')) ? 'true': 'false';
if ($this->get('showfilter'))
{
$html.= '<div id="'.$this->listingId.'_search_container" class="'.self::CLASS_PREFIX.'search_container">'."\n";
$html.= "\t".'<span class="'.self::CLASS_PREFIX.'filterlabel">'.JText::_('PLG_CONTENT_EFLP_SEARCH_TEXT').'</span>'."\n";
$html.= "\t".'<input type="text" id="'.$this->listingId.'_textbox" class="eflpro_textboxes">'."\n";
$html.= "\t".'<img id="'.$this->listingId.'_cancelimg" class="'.self::CLASS_PREFIX.'cancelimgs" src="'.$this->config->get('cancelicon').'" alt="'.JText::_($this->config->get('cancelalt')).'" />'."\n";
$html.= "\t".'<div id="'.$this->listingId.'_search_results" class="'.self::CLASS_PREFIX.'search_results">'."\n";
$html.= "\t".'</div>'."\n";
$html.= '</div>'."\n";
$html.= "\n".'<script type="text/javascript">'."\n";
if ($this->mootools)
{
$html.= 'var eflproSearch'.$this->listingId." = new EFLPMooSearch('".$this->listingId."', ".$textLength.", { ";
$html.= "esc:".$esc.", ";
$html.= "wait:".$this->get('filterwait')." ";
$html.= "});\n";
}
else
{
$html.= 'var eflproSearch'.$this->listingId." = new EFLPJQySearch('".$this->listingId."', ".$textLength.", { ";
$html.= "esc:".$esc.", ";
$html.= "wait:".$this->get('filterwait')." ";
$html.= "});\n";
$html.= 'eflproSearch'.$this->listingId.'.setupSearch();'."\n";
}
$html.= "\n".'</script>';
}
return $html;
}
/**
* Adds all the html controls related to the multi-download functions
*/
protected function addMultiDownloadPanel()
{
//just return nothing if multi-download is disabled
if (!$this->get('multidownload'))
{
return '';
}
//need multi-select for multi-download
JHtml::_('behavior.multiselect');
$this->addMultiDownloadJS();
$html = '<div id="'.$this->listingId.'_multidownload_panel">'."\n";
//Add div with archive selection and button
if ($this->get('archivetype') == 'all')
{
$html.= '<label for="archivetype">'.JText::_('PLG_CONTENT_EFLP_CHOOSE_ARCHIVE_LABEL').' : </label>';
$html.= '<select id="archivetype" name="archivetype">'."\n";
$zip = false;
$gz = false;
if (MultiDownload::canCreateArchive('zip') == true)
{
$zip = true;
$html.= '<option selected value="zip">'.JText::_('PLG_CONTENT_EFLP_ZIP_ARCHIVE').'</option>'."\n";
}
if (MultiDownload::canCreateArchive('gz') == true)
{
$gz = true;
$html.= '<option '.(($zip == false) ? 'selected ': '').'value="gz">'.JText::_('PLG_CONTENT_EFLP_GZ_ARCHIVE').'</option>'."\n";
}
if (MultiDownload::canCreateArchive('bz2') == true)
{
$html.= '<option '.(($zip == false && $gz == false) ? 'selected ' : '').'value="bz2">'.JText::_('PLG_CONTENT_EFLP_BZ_ARCHIVE').'</option>'."\n";
}
$html.= '</select>'."\n";
}
else
{
$html.= '<input type="hidden" name="archivetype" id="archivetype" value="'.$this->get('archivetype').'" />'."\n";
}
$html.= '<button class="btn" id="'.$this->listingId.'_download_button" name="'.$this->listingId.'_download_button" type="submit" value="1">'.JText::_('PLG_CONTENT_EFLP_DOWNLOAD_TEXT').'</button>'."\n";
$html.= '<input type="hidden" name="archive_download" id="archive_download" value="1" />'."\n";
$html.= "\t".'<div id="'.$this->listingId.'_multidownload_limits">'."\n";
$html.= "\t\t".'<span>'.JText::_('PLG_CONTENT_EFLP_TOTAL_NUMBER_TEXT').'</span><span id="'.$this->listingId.'_totalnumber"></span>';
$html.= '<br />';
$html.= "\t\t".'<span>'.JText::_('PLG_CONTENT_EFLP_TOTAL_SIZE_TEXT').'</span><span id="'.$this->listingId.'_totalsize"></span>';
$html.= "\t".'</div>'."\n";
$html.= '</div>'."\n";
return $html;
}
protected function addMultiDownloadJS()
{
$js = '';
if ($this->mootools)
{
$js.= "\t".'var eflproLimits'.$this->listingId." = new EFLPMooLimits('".$this->listingId."', { ";
$js.= "maxsize:".$this->get('maxsizefiles').", ";
$js.= "maxnumber:".$this->get('maxnumberfiles')." ";
$js.= "});\n";
}
else
{
$js.= "\t".'var eflproLimits'.$this->listingId." = new EFLPJQyLimits('".$this->listingId."', { ";
$js.= "maxsize:".$this->get('maxsizefiles').", ";
$js.= "maxnumber:".$this->get('maxnumberfiles')." ";
$js.= "});\n";
$js.= 'eflproLimits'.$this->listingId.'.setupLimits();'."\n";
}
$document = JFactory::getDocument();
$document->addScriptDeclaration($js);
}
/**
* Adds the html icon that allows the user to collapse or expand the entire listing
*/
protected function addCollapseExpandControl()
{
$html = '';
if ($this->get('showcollapseexpand'))
{
$html.= '<div>'."\n";
$html.= "\t".'<div id="'.$this->listingId.'_collapse" class="'.self::CLASS_PREFIX.'collapseall">';
$html.= '<img src="'.$this->config->get('collapseicon').'" alt="'.JText::_($this->config->get('collapsealt')).'" /></div>'."\n";
$html.= "\t".'<div id="'.$this->listingId.'_expand" class="'.self::CLASS_PREFIX.'expandall">';
$html.= '<img src="'.$this->config->get('expandicon').'" alt="'.JText::_($this->config->get('expandalt')).'" /></div>'."\n";
$html.= '</div>'."\n";
}
return $html;
}
/**
* Configures the headings by calculating their width, and sorting them. Returns an array
* with the headings data already pre-sorted.
*/
protected function processHeadings($cols)
{
//only monitoring the heading columns
if ($this->get('multidownload')) { $cols--; }
//process the ratio text
$split = array_map('floatval', array_map('trim', explode(':', $this->get('ratio'))));
//filename is always first, with index 0
$this->headings[0]['type'] = 'name';
//add relpath column, if needed
if ($this->get('subfoldercolumn'))
{
//relpath is always 1
$this->headings[1]['type'] = 'relpath';
}
//add the size column, if needed
if ($this->get('size'))
{
$sizeindex = 4;
if ($this->get('sizefirst'))
{
$sizeindex = 2;
}
$this->headings[$sizeindex]['type'] = 'size';
}
//add the date column, if needed
if ($this->get('date'))
{
//date always has index 3
$this->headings[3]['type'] = 'date';
}
//sort resulting array by key
ksort($this->headings);
//reset the keys
$this->headings = array_values($this->headings);
//ratio should have the same number of values as the columns
if (count($split) != $cols)
{
//reset the ratio array
$split = array();
//invalid ratio, since it is less than the number of columns. use defaults.
if ($cols == 4)
{
$split[0] = 0.4;
$split[1] = 0.2;
$split[2] = 0.2;
$split[3] = 0.2;
}
elseif ($cols == 3)
{
$split[0] = 0.6;
$split[1] = 0.2;
$split[2] = 0.2;
}
elseif ($cols == 2)
{
$split[0] = 0.8;
$split[1] = 0.2;
}
elseif ($cols == 1)
{
$split[0] = 1;
}
}
//calculate the ratio total
$total = 0.0;
foreach ($split as $ratio) { $total += $ratio; }
for ($i=0; $i<$cols; $i++)
{
$this->headings[$i]['ratio'] = $split[$i];
$this->headings[$i]['percent'] = (int)floor(($split[$i] * 100.0) / $total);
}
}
/**
* Adds an input checkbox for the file based on index. Used for multi-file downloading
*/
protected function addCheckbox($index)
{
$html = '';
if ($this->get('multidownload'))
{
//encrypt the filename and path
$data = ValorUtilities::obfuscate(array('path'=>$this->files[$index]['relpath'].'/'.$this->files[$index]['filename'].'.'.$this->files[$index]['ext'], 'size'=>$this->files[$index]['bytes']));
//TODO: Add functionality to check archive size before download
//add the checkbox for the file
$html.= '<input type="checkbox" id="cb'.$index.'" name="cid[]" value="'.$data.'" data-bytes="'.$this->files[$index]['bytes'].'" onchange="eflproLimits'.$this->listingId.'.checkFile(this);" title="Checkbox for file '.$this->files[$index]['filename'].'.'.$this->files[$index]['ext'].'" />';
//add a space after
$html.= ' ';
}
return $html;
}
/**
* Formats the file name and links it.
*/
protected function formatFilename($index)
{
$html = '';
//add icon
if ($this->get('icons'))
{
$html.= $this->attachFileIcon($this->files[$index]['ext']);
}
//format the filename with utf-8 encoding if needed
$filename = $this->fixLang($this->files[$index]['filename']);
//add the extension to the file
if ($this->get('extensions'))
{
$filename.= '.'.$this->files[$index]['ext'];
}
//add all the linkage
$html.= $this->formatLinks($filename, $index);
return $html;
}
/**
* Adds the HTML code to display folder icons relating to the files
* Note: There is a space at the end of the img tag.
*/
protected function attachFileIcon($ext)
{
$html = '';
//check all the published icons
foreach ($this->iconsdata as $i => $icon)
{
if (stripos($icon['exts'], $ext) !== false && ValorUtilities::isUserAllowed($icon['access']))
{
//display the icon related to the file type
$html .= '<img src="'.$icon['location'].'" alt="'.JText::_($icon['alt']).'" /> ';
break;
}
}
if (empty($html))
{
//display the default icon
$html .= '<img src="'.$this->config->get('defaulticon').'" alt="'.JText::_($this->config->get('defaultalt')).'" /> ';
}
return $html;
}
/**
* Formats the string according to UTF-8 options specified in the component configuration
*/
protected function fixLang($text)
{
if ($this->config->get('force_utf8') == 4)
{
return JString::transcode($text, $this->config->get('src_encoding'), "UTF-8");
}
elseif ($this->config->get('force_utf8') == 3)
{
return iconv($this->config->get('src_encoding'), 'UTF-8', $text);
}
elseif ($this->config->get('force_utf8') == 2)
{
return iconv($this->config->get('src_encoding'), 'UTF-8//IGNORE', $text);
}
elseif ($this->config->get('force_utf8') == 1)
{
return utf8_encode($text);
}
else //0
{
return $text;
}
}
/**
* Adds all the links relating to the file. Links the filename, download icon and
* preview icon, based on parameters.
*/
protected function formatLinks($datum, $index)
{
$html = '';
//determine whether you can download or preview the file, based on its type
$canDownload = $this->validForDownload($this->files[$index]['ext']);
$canPreview = $this->validForPreview($this->files[$index]['ext']);
//format the file name linkage
if ($this->get('preview') == 'link' && $canPreview == true)
{
$html .= $this->formatPreview($datum, $index);
}
elseif ($this->get('download') == 'link' && $canDownload == true)
{
$html .= $this->formatDownload($datum, $index);
}
elseif ($this->get('linktofiles'))
{
$html .= $this->formatPlainLink($datum, $index);
}
else
{
$html .= $datum;
}
$icons = '';
//force download with icon
if ($this->get('download') == 'icon' && $canDownload == true)
{
//generate the html img for the download icon
$icon = '<img src="'.$this->config->get('downloadicon').'" alt="'.JText::_($this->config->get('downloadalt')).'" /> ';
//make it a link
$icons .= $this->formatDownload($icon, $index);
}
//preview with icon
if ($this->get('preview') == 'icon' && $canPreview == true)
{
//generate the html img for the preview icon
$icon = '<img src="'.$this->config->get('previewicon').'" alt="'.JText::_($this->config->get('previewalt')).'" /> ';
//make it a link
$icons .= $this->formatPreview($icon, $index);
}
//determine where to place icons
if ($this->get('iconsafter'))
{
$html.= $icons;
}
else
{
$html = $icons.$html;
}
return $html;
}
/**
* Checks of the file type is valid for downloading
*/
protected function validForDownload($ext)
{
$valid = true;
if (stripos(self::INVALID_EXTS, $ext) !== false)
{
$valid = false;
}
return $valid;
}
/**
* Checks of the file type is valid for preview via Google Docs Viewer
*/
protected function validForPreview($ext)
{
$valid = false;
$list = self::BROWSER_PREVIEW_EXTS;
if ($this->get('previewer') == 'google')
{
$list = self::GOOGLE_PREVIEW_EXTS;
}
if (stripos($list, $ext) !== false)
{
$valid = true;
}
//preview any file if previewer set to none
if ($this->get('previewer') == 'none')
{
$valid = true;
}
return $valid;
}
/**
* Surrounds the given text in an anchor tag that previews the file link in a modal
* view using either Google Docs Viewer or the native browser viewer.
*/
protected function formatPreview($datum, $index)
{
$html = '';
//initialize width and height. force cast to int, just in case
$width = (int) $this->get('modalwidth');
$height = (int) $this->get('modalheight');
//find out what type of file we are dealing with
if ($this->files[$index]['image'])
{
//save the modal dimensions
$modal_width = $width;
$modal_height = $height;
//get dimensions from file array
$width = $this->files[$index]['image']['width'];
$height = $this->files[$index]['image']['height'];
//customize dimensions
if ($width > $modal_width || $height > $modal_height)
{
if (($width / $modal_width) > ($height / $modal_height))
{
$width = $modal_width;
$height = $modal_width * $height / $width;
$height = intval($height);
}
else
{
$width = $modal_height * $width / $height;
$width = intval($width);
$height = $modal_height;
}
}
}
//get the modal type
$modaltype = $this->get('modaltype');
if ($this->mootools || $modaltype == 'mootools')
{
$html .= '<a class="'.self::MODAL_MOO.'" rel="{handler: \'iframe\', size: {x: '.$width.', y: '.$height.'}}" href="'.$this->previewURL($index).'">'.$datum.'</a>';
}
elseif ($modaltype == 'auto')
{
$html.= '<a class="'.self::MODAL_JQY.'" data-modal="'.self::MODAL_ID.'" data-xsize="'.$width.'" data-ysize="'.$height.'" href="'.$this->previewURL($index).'">'.$datum.'</a>';
}
else //$modaltype == 'none'
{
$html.= '<a href="'.$this->previewURL($index).'" target="'.$this->get('target').'">'.$datum.'</a>';
}
return $html;
}
/**
* Formulates the Preview URL to fit the google docs viewer or the native browser
*/
protected function previewURL($index, $embed = true)
{
$embed_val = 1;
if($embed == false)
{
$embed_val = 0;
}
//create the url with the file data
$uri = 'index.php?option=com_easyfolderlistingpro&view=preview&format=raw&data='.$this->obfuscatedFileData($index);
$url = JRoute::_($uri, false);
//specify the return link
$link = $url;
//alter the link to accommodate Google Docs Viewer
if (!$this->files[$index]['image'] && $this->get('previewer') == 'google')
{
$parts = parse_url(JURI::base());
$url = $parts['scheme'].'://'.$parts['host'].(empty($parts['port'])?'':':'.$parts['port']).$url;
$link = 'http://docs.google.com/viewer?url='.rawurlencode($url);
if ($embed == true)
{
$link.= '&embedded=true';
}
}
return $link;
}
/**
* Obfuscates the data needed to preview/download files
*/
protected function obfuscatedFileData($index, $attachment = true)
{
$data = array();
$data['folder'] = $this->get('folder');
$data['userfolders'] = $this->get('userfolders');
$data['guestfolder'] = $this->get('guestfolder');
$data['username'] = $this->username;
$data['userid'] = $this->userId;
$data['relpath'] = $this->files[$index]['relpath'];
$data['filename'] = $this->files[$index]['filename'];
$data['ext'] = $this->files[$index]['ext'];
$data['expires'] = $this->expires;
$data['attachment'] = $attachment;
$data['previewer'] = $this->get('previewer');
return ValorUtilities::obfuscate($data);
}
/**
* Surrounds the given text with an anchor tag that references the (attachment) download link for a file
*/
protected function formatDownload($datum, $index)
{
$html = '<a class="'.self::CLASS_PREFIX.'download" href="'.$this->downloadURL($index).'" target="_blank">'.$datum.'</a>';
return $html;
}
/**
* Formulates the download URL related to a file
*/
protected function downloadURL($index, $attachment = true)
{
$url = '';
if (!$this->get('obfuscatelink') && $this->isInJoomlaRoot == true)
{
//trim path, just in case
$path = trim($this->get('folder'));
//trim forward slashes and backslashes from only the end of the path
$path = rtrim($path, "/\\");
//add userfolder if required. leave as-is if userfolders disabled.
$path = ValorUtilities::userbasedPath($path, $this->get('userfolders'), $this->get('guestfolder'), $this->username);
//define the relative path to the file
$relfilepath = $this->files[$index]['relpath'].'/'.$this->files[$index]['filename'].'.'.$this->files[$index]['ext'];
//put together the file path
$path.= $relfilepath;
$path = ValorUtilities::changeSlashes($path, '/');
//assign path to url variable
$url = $path;
}
else
{
$uri = 'index.php?option=com_easyfolderlistingpro&view=download&format=raw&data='.$this->obfuscatedFileData($index, $attachment);
$url = JRoute::_($uri, false);
}
return $url;
}
/**
* Surrounds the text with an anchor tag allowing the user to download the file as inline.
*/
protected function formatPlainLink($datum, $index)
{
$html = '<a href="'.$this->downloadURL($index, false).'" target="'.$this->get('target').'">'.$datum.'</a>';
return $html;
}
/**
* Formats the file's unix timestamp to a human readable date format
*/
protected function readableDateTime($time)
{
if ($this->get('time'))
{
//show date and time
return date($this->get('timeformat'), $time);
}
else
{
//show date only
return date($this->get('dateformat'), $time);
}
}
/**
* Converts a file size in bytes to a human readable form
*/
protected function readableFileSize($size)
{
return ValorUtilities::sizeToText($size);
}
/**
* Compiles the archive settings in an array serializes it as an obfuscated text
*/
protected function serializeArchiveSettings()
{
//initialize the settings array
$settings = array();
//assign the necessary archive settings
$settings['folder'] = $this->get('folder');
$settings['userfolders'] = $this->get('userfolders');
$settings['guestfolder'] = $this->get('guestfolder');
$settings['username'] = $this->username;
$settings['userid'] = $this->userId;
/* Note: don't save archivetype from parameters. It is taken from form front-end. */
$settings['maxsizefiles'] = $this->get('maxsizefiles');
$settings['maxnumberfiles'] = $this->get('maxnumberfiles');
$settings['archivelife'] = $this->get('archivelife');
return ValorUtilities::obfuscate($settings);
}
/**
* Adds the folder name with icon and non-ascii characters fixed
*/
protected function formatSubfolderName($index)
{
//specify the path
$html = '';
if (!empty($this->folders))
{
if ($this->get('icons'))
{
$html.= '<img src="'.$this->config->get('subfoldericon').'" alt="'.JText::_($this->config->get('subfolderalt')).'" /> ';
}
$html.= $this->fixLang($this->folders[$index]['name']);
}
return $html;
}
}