Guest User

Untitled

a guest
Sep 14th, 2016
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 106.10 KB | None | 0 0
  1. <?php
  2. /**
  3. * @package      EasyDiscuss
  4. * @copyright    Copyright (C) 2010 - 2015 Stack Ideas Sdn Bhd. All rights reserved.
  5. * @license      GNU/GPL, see LICENSE.php
  6. * EasyDiscuss is free software. This version may have been modified pursuant
  7. * to the GNU General Public License, and as distributed it includes or
  8. * is derivative of works licensed under the GNU General Public License or
  9. * other free or open source software licenses.
  10. * See COPYRIGHT.php for copyright notices and details.
  11. */
  12. defined('_JEXEC') or die('Unauthorized Access');
  13.  
  14. jimport('joomla.filesystem.file');
  15. jimport('joomla.filesystem.folder');
  16. jimport('joomla.html.parameter');
  17. jimport('joomla.access.access');
  18. jimport('joomla.application.component.model');
  19.  
  20. // Include legacy object
  21. require_once(__DIR__ . '/legacy.php');
  22.  
  23. // Include constants
  24. require_once(__DIR__ . '/dependencies.php');
  25.  
  26. class ED
  27. {
  28.     /**
  29.      * Initializes the css, js and necessary dependencies for EasyDiscuss
  30.      *
  31.      * @since   4.0
  32.      * @access  public
  33.      * @param   string
  34.      * @return
  35.      */
  36.     public static function init($location = 'site')
  37.     {
  38.         static $loaded = array();
  39.  
  40.         if (!isset($loaded[$location])) {
  41.  
  42.             $input = JFactory::getApplication()->input;
  43.  
  44.             // Determines if we should force compilationg (Only allow for super admin)
  45.             $recompile = false;
  46.  
  47.             if (ED::isSiteAdmin()) {
  48.                 $recompile = $input->get('compile', false, 'bool');
  49.             }
  50.  
  51.             // If location is provided, we should respect the location
  52.             $customLocation = $input->get('location', $location, 'word');
  53.             $locations = array($location);
  54.  
  55.             if ($recompile && $customLocation == 'all') {
  56.                 $locations = array('site', 'admin');
  57.             }
  58.  
  59.             foreach ($locations as $location) {
  60.                 // Render the JS compiler
  61.                 $compiler = ED::compiler($location);
  62.  
  63.                 if ($recompile) {
  64.                     $compiler->compile(true, true);
  65.                 }
  66.             }
  67.  
  68.             // Attach those scripts onto the head of the page now.
  69.             $compiler->attach();
  70.  
  71.             // Attach the stylesheets
  72.             $stylesheet = ED::stylesheet($location);
  73.             $stylesheet->attach();
  74.  
  75.             $loaded[$location] = true;
  76.         }
  77.  
  78.         return $loaded[$location];
  79.     }
  80.  
  81.     /**
  82.      * Formats and returns the appropriate cdn url
  83.      *
  84.      * @since   4.0
  85.      * @access  public
  86.      * @param   string
  87.      * @return
  88.      */
  89.     public static function getCdnUrl()
  90.     {
  91.         static $cdnUrl = false;
  92.  
  93.         if (!$cdnUrl) {
  94.             $config = ED::config();
  95.             $cdnUrl = $config->get('system_cdn_url');
  96.  
  97.             if (!$cdnUrl) {
  98.                 return $cdnUrl;
  99.             }
  100.  
  101.             if (stristr($cdnUrl, 'http://') === false && stristr($cdnUrl, 'https://') === false) {
  102.                 $cdnUrl = 'http://' . $cdnUrl;
  103.             }
  104.         }
  105.  
  106.         return $cdnUrl;
  107.     }
  108.  
  109.     /**
  110.      * Singleton version for the ajax library
  111.      *
  112.      * @since   4.0
  113.      * @access  public
  114.      * @param   string
  115.      * @return
  116.      */
  117.     public static function ajax()
  118.     {
  119.         static $ajax = null;
  120.  
  121.         if (!$ajax) {
  122.  
  123.             require_once(__DIR__ . '/ajax/ajax.php');
  124.  
  125.             $ajax = new EasyDiscussAjax();
  126.         }
  127.  
  128.         return $ajax;
  129.     }
  130.  
  131.     public static function _()
  132.     {
  133.         return ED::getHelper( func_get_args() );
  134.     }
  135.  
  136.     /**
  137.      * Retrieves the token
  138.      *
  139.      * @since   4.0
  140.      * @access  public
  141.      * @param   string
  142.      * @return
  143.      */
  144.     public static function getToken($contents = '')
  145.     {
  146.         $token = JFactory::getSession()->getFormToken();
  147.  
  148.         return $token;
  149.     }
  150.  
  151.     public static function getHash( $seed = '' )
  152.     {
  153.         if( DiscussHelper::getJoomlaVersion() >= '2.5' )
  154.         {
  155.             return JApplication::getHash( $seed );
  156.         }
  157.  
  158.         return JUtility::getHash( $seed );
  159.     }
  160.  
  161.     /**
  162.      * Retrieves a jdate object with the correct speficied timezone offset
  163.      *
  164.      * @since   4.0
  165.      * @access  public
  166.      * @param   string
  167.      * @return
  168.      */
  169.     public static function dateWithOffSet($str='')
  170.     {
  171.         $userTZ = self::getTimeZoneOffset();
  172.         $date = ED::date($str);
  173.  
  174.         $user = JFactory::getUser();
  175.         $config = ED::Config();
  176.         $jConfig = ED::JConfig();
  177.  
  178.         // temporary ignore the dst in joomla 1.6
  179.  
  180.         if ($user->id != 0) {
  181.             $userTZ = $user->getParam('timezone');
  182.         }
  183.  
  184.         if (empty($userTZ)) {
  185.             $userTZ = $jConfig->get('offset');
  186.         }
  187.  
  188.         $tmp = new DateTimeZone($userTZ);
  189.         $date->setTimeZone($tmp);
  190.  
  191.         return $date;
  192.     }
  193.  
  194.     public static function getBBCodeParser() {
  195.         require_once( DISCUSS_CLASSES . '/decoda.php');
  196.         $decoda = new DiscussDecoda( '', array('strictMode'=>false) );
  197.         return $decoda;
  198.     }
  199.  
  200.     public static function getHelper()
  201.     {
  202.         static $helpers = array();
  203.  
  204.         $args = func_get_args();
  205.  
  206.         if (func_num_args() == 0 || empty($args) || empty($args[0]))
  207.         {
  208.             return false;
  209.         }
  210.  
  211.         $sig = md5(serialize($args));
  212.  
  213.         if( !array_key_exists($sig, $helpers) )
  214.         {
  215.             $helper = preg_replace('/[^A-Z0-9_\.-]/i', '', $args[0]);
  216.             $file = DISCUSS_HELPERS . '/' . JString::strtolower($helper) . '.php';
  217.  
  218.             if( JFile::exists($file) )
  219.             {
  220.                 require_once($file);
  221.                 $class  = 'Discuss' . ucfirst( $helper ) . 'Helper';
  222.  
  223.                 switch (func_num_args()) {
  224.                     case '2':
  225.                         $helpers[$sig]  = new $class($args[1]);
  226.                         break;
  227.                     case '3':
  228.                         $helpers[$sig]  = new $class($args[1], $args[2]);
  229.                         break;
  230.                     case '4':
  231.                         $helpers[$sig]  = new $class($args[1], $args[2], $args[3]);
  232.                         break;
  233.                     case '5':
  234.                         $helpers[$sig]  = new $class($args[1], $args[2], $args[3], $args[4]);
  235.                         break;
  236.                     case '6':
  237.                         $helpers[$sig]  = new $class($args[1], $args[2], $args[3], $args[4], $args[5]);
  238.                         break;
  239.                     case '7':
  240.                         $helpers[$sig]  = new $class($args[1], $args[2], $args[3], $args[4], $args[5], $args[6]);
  241.                         break;
  242.                     case '1':
  243.                     default:
  244.                         $helpers[$sig]  = new $class();
  245.                         break;
  246.                 }
  247.             }
  248.             else
  249.             {
  250.                 $helpers[$sig]  = false;
  251.             }
  252.         }
  253.  
  254.         return $helpers[$sig];
  255.     }
  256.  
  257.     /**
  258.      * Retrieve specific helper objects.
  259.      *
  260.      * @param   string  $helper The helper class . Class name should be the same name as the file. e.g EasyDiscussXXXHelper
  261.      * @return  object  Helper object.
  262.      **/
  263.     public static function getHelperLegacy( $helper )
  264.     {
  265.         static $obj = array();
  266.  
  267.         if( !isset( $obj[ $helper ] ) )
  268.         {
  269.             $file   = DISCUSS_HELPERS . '/' . JString::strtolower( $helper ) . '.php';
  270.  
  271.             if( JFile::exists( $file ) )
  272.             {
  273.                 require_once( $file );
  274.                 $class  = 'Discuss' . ucfirst( $helper ) . 'Helper';
  275.  
  276.                 $obj[ $helper ] = new $class();
  277.             }
  278.             else
  279.             {
  280.                 $obj[ $helper ] = false;
  281.             }
  282.         }
  283.  
  284.         return $obj[ $helper ];
  285.     }
  286.  
  287.     public static function getRegistry( $data = '' )
  288.     {
  289.         if( ED::getJoomlaVersion() >= '1.6' )
  290.         {
  291.             $registry = new JRegistry($data);
  292.         }
  293.         else
  294.         {
  295.             require_once DISCUSS_CLASSES . '/registry.php';
  296.             $registry = new DiscussRegistry($data);
  297.         }
  298.  
  299.         return $registry;
  300.     }
  301.  
  302.     public static function getXML($data, $isFile = true)
  303.     {
  304.         if( ED::getJoomlaVersion() >= '1.6' )
  305.         {
  306.             $xml = JFactory::getXML($data, true);
  307.         }
  308.         else
  309.         {
  310.             // Disable libxml errors and allow to fetch error information as needed
  311.             libxml_use_internal_errors(true);
  312.  
  313.             if ($isFile)
  314.             {
  315.                 // Try to load the XML file
  316.                 //$xml = simplexml_load_file($data, 'JXMLElement');
  317.                 $xml = simplexml_load_file($data);
  318.             }
  319.             else
  320.             {
  321.                 // Try to load the XML string
  322.                 //$xml = simplexml_load_string($data, 'JXMLElement');
  323.                 $xml = simplexml_load_string($data);
  324.             }
  325.  
  326.             if (empty($xml))
  327.             {
  328.                 // There was an error
  329.                 JError::raiseWarning(100, JText::_('JLIB_UTIL_ERROR_XML_LOAD'));
  330.  
  331.                 if ($isFile)
  332.                 {
  333.                     JError::raiseWarning(100, $data);
  334.                 }
  335.  
  336.                 foreach (libxml_get_errors() as $error)
  337.                 {
  338.                     JError::raiseWarning(100, 'XML: ' . $error->message);
  339.                 }
  340.             }
  341.         }
  342.  
  343.         return $xml;
  344.     }
  345.  
  346.     public static function getUnansweredCount( $categoryId = '0', $excludeFeatured = false )
  347.     {
  348.         $db     = DiscussHelper::getDBO();
  349.  
  350.         $excludeCats    = DiscussHelper::getPrivateCategories();
  351.         $catModel       = ED::model('Categories');
  352.  
  353.         if( !is_array( $categoryId ) && !empty( $categoryId ))
  354.         {
  355.             $categoryId     = array( $categoryId );
  356.         }
  357.  
  358.         $childs         = array();
  359.         if( $categoryId )
  360.         {
  361.             foreach( $categoryId as $id )
  362.             {
  363.                 $data       = $catModel->getChildIds( $id );
  364.  
  365.                 if( $data )
  366.                 {
  367.                     foreach( $data as $childCategory )
  368.                     {
  369.                         $childs[]   = $childCategory;
  370.                     }
  371.                 }
  372.                 $childs[]       = $id;
  373.             }
  374.         }
  375.  
  376.         if( !$categoryId )
  377.         {
  378.             $categoryIds    = false;
  379.         }
  380.         else
  381.         {
  382.             $categoryIds    = array_diff($childs, $excludeCats);
  383.         }
  384.  
  385.         $query  = 'SELECT COUNT(a.`id`) FROM `#__discuss_posts` AS a';
  386.         $query  .= '  LEFT JOIN `#__discuss_posts` AS b';
  387.         $query  .= '    ON a.`id`=b.`parent_id`';
  388.         $query  .= '    AND b.`published`=' . $db->Quote('1');
  389.         $query  .= ' WHERE a.`parent_id` = ' . $db->Quote('0');
  390.         $query  .= ' AND a.`published`=' . $db->Quote('1');
  391.         $query  .= ' AND  a.`answered` = 0';
  392.         $query  .= ' AND a.`isresolve`=' . $db->Quote('0');
  393.         $query  .= ' AND b.`id` IS NULL';
  394.  
  395.  
  396.         if( $categoryIds )
  397.         {
  398.             if( count( $categoryIds ) == 1 )
  399.             {
  400.                 $categoryIds    = array_shift( $categoryIds );
  401.                 $query .= ' AND a.`category_id` = ' . $db->Quote( $categoryIds );
  402.             }
  403.             else
  404.             {
  405.                 $query .= ' AND a.`category_id` IN (' . implode( ',', $categoryIds ) .')';
  406.             }
  407.         }
  408.  
  409.         if( $excludeFeatured )
  410.         {
  411.             $query  .= ' AND a.`featured`=' . $db->Quote( '0' );
  412.         }
  413.  
  414.         if (!ED::isSiteAdmin() && !ED::isModerator()) {
  415.             $query  .= ' AND a.`private`=' . $db->Quote(0);
  416.         }
  417.  
  418.  
  419.         $db->setQuery( $query );
  420.  
  421.         return $db->loadResult();
  422.     }
  423.  
  424.     public static function getFeaturedCount( $categoryId )
  425.     {
  426.         $db = DiscussHelper::getDBO();
  427.  
  428.         $query  = 'SELECT COUNT(1) as `CNT` FROM `#__discuss_posts` AS a';
  429.  
  430.         $query  .= ' WHERE a.`featured` = ' . $db->Quote('1');
  431.         $query  .= ' AND a.`parent_id` = ' . $db->Quote('0');
  432.         $query  .= ' AND a.`published` = ' . $db->Quote('1');
  433.         $query  .= ' AND a.`category_id`= ' . $db->Quote( $categoryId );
  434.  
  435.         $db->setQuery($query);
  436.  
  437.         $result = $db->loadResult();
  438.  
  439.         return $result;
  440.     }
  441.  
  442.     /**
  443.      * Allows caller to queue a message
  444.      *
  445.      * @since   4.0
  446.      * @access  public
  447.      * @param   string
  448.      * @return
  449.      */
  450.     public static function setMessage($message, $type = 'info')
  451.     {
  452.         $session = JFactory::getSession();
  453.  
  454.         $msgObj = new stdClass();
  455.         $msgObj->message = JText::_($message);
  456.         $msgObj->type = strtolower($type);
  457.  
  458.         //save messsage into session
  459.         $session->set('discuss.message.queue', $msgObj, 'DISCUSS.MESSAGE');
  460.     }
  461.  
  462.     public static function getMessageQueue()
  463.     {
  464.         $session    = JFactory::getSession();
  465.         $msgObj     = $session->get('discuss.message.queue', null, 'DISCUSS.MESSAGE');
  466.  
  467.         //clear messsage into session
  468.         $session->set('discuss.message.queue', null, 'DISCUSS.MESSAGE');
  469.  
  470.         return $msgObj;
  471.     }
  472.  
  473.     public static function getAlias( $title, $type='post', $id='0' )
  474.     {
  475.  
  476.         $items = explode( ' ', $title );
  477.         foreach( $items as $index => $item )
  478.         {
  479.             if( strpos( $item, '*' ) !== false  )
  480.             {
  481.                 $items[$index] = 'censored';
  482.             }
  483.         }
  484.  
  485.         $title = implode( $items, ' ' );
  486.  
  487.         $alias  = DiscussHelper::permalinkSlug($title);
  488.  
  489.         // Make sure no such alias exists.
  490.         $i  = 1;
  491.         while( DiscussRouter::_isAliasExists( $alias, $type, $id ) )
  492.         {
  493.             $alias  = DiscussHelper::permalinkSlug( $title ) . '-' . $i;
  494.             $i++;
  495.         }
  496.  
  497.         return $alias;
  498.     }
  499.  
  500.     public static function permalinkSlug( $string, $uid = null )
  501.     {
  502.         $config     = DiscussHelper::getConfig();
  503.         if ($config->get( 'main_sef_unicode' )) {
  504.  
  505.             if ($uid && is_numeric($uid)) {
  506.                 $string = $uid . ':' . $string;
  507.             }
  508.  
  509.             // Unicode support.
  510.             $alias  = DiscussHelper::permalinkUnicodeSlug($string);
  511.  
  512.         } else {
  513.             // Replace accents to get accurate string
  514.             //$alias    = DiscussRouter::replaceAccents( $string );
  515.             // hällö wörldß became hallo-world instead haelloe-woerld thus above line is commented
  516.             // for consistency with joomla
  517.  
  518.             $alias  = JFilterOutput::stringURLSafe( $string );
  519.  
  520.             // check if anything return or not. If not, then we give a date as the alias.
  521.             if(trim(str_replace('-', '', $alias)) == '') {
  522.                 $alias = ED::date()->format("Y-m-d-H-i-s");
  523.             }
  524.         }
  525.         return $alias;
  526.     }
  527.  
  528.     public static function permalinkUnicodeSlug( $string )
  529.     {
  530.         $slug   = '';
  531.         if(DiscussHelper::getJoomlaVersion() >= '1.6')
  532.         {
  533.             $slug   = JFilterOutput::stringURLUnicodeSlug($string);
  534.         }
  535.         else
  536.         {
  537.             //replace double byte whitespaces by single byte (Far-East languages)
  538.             $slug = preg_replace('/\xE3\x80\x80/', ' ', $string);
  539.  
  540.             // remove any '-' from the string as they will be used as concatenator.
  541.             // Would be great to let the spaces in but only Firefox is friendly with this
  542.             $slug = str_replace('-', ' ', $slug);
  543.  
  544.             // replace forbidden characters by whitespaces
  545.             $slug = preg_replace( '#[:\#\*"@+=;!><&\.%()\]\/\'\\\\|\[]#', "\x20", $slug );
  546.  
  547.             //delete all '?'
  548.             $slug = str_replace('?', '', $slug);
  549.  
  550.             //trim white spaces at beginning and end of alias, make lowercase
  551.             $slug = trim(JString::strtolower($slug));
  552.  
  553.             // remove any duplicate whitespace and replace whitespaces by hyphens
  554.             $slug =preg_replace('#\x20+#','-', $slug);
  555.         }
  556.  
  557.         return $slug;
  558.     }
  559.  
  560.     public static function getNotification()
  561.     {
  562.         static $notify = false;
  563.  
  564.         if( !$notify )
  565.         {
  566.  
  567.             $notify = ED::notifications();
  568.         }
  569.         return $notify;
  570.  
  571.     }
  572.  
  573.     public static function getMailQueue()
  574.     {
  575.         static $mailq = false;
  576.  
  577.         if (!$mailq) {
  578.             $mailq = ED::mailqueue();
  579.         }
  580.  
  581.         return $mailq;
  582.     }
  583.  
  584.     public static function getSiteSubscriptionClass()
  585.     {
  586.         static $sitesubscriptionclass = false;
  587.  
  588.         if( !$sitesubscriptionclass )
  589.         {
  590.             require_once DISCUSS_CLASSES . '/subscription.php';
  591.  
  592.             $sitesubscriptionclass  = new DiscussSubscription();
  593.         }
  594.         return $sitesubscriptionclass;
  595.     }
  596.  
  597.     public static function getLoginHTML( $returnURL )
  598.     {
  599.         $tpl    = new DiscussThemes();
  600.         $tpl->set( 'return' , base64_encode( $returnURL ) );
  601.  
  602.         return $tpl->fetch( 'ajax.login.php' );
  603.     }
  604.  
  605.     public static function getLocalParser()
  606.     {
  607.         $data       = new stdClass();
  608.  
  609.         $contents   = JFile::read( DISCUSS_ADMIN_ROOT . '/easydiscuss.xml' );
  610.  
  611.         $parser     = new DiscussXMLHelper( $contents );
  612.  
  613.         return $parser;
  614.     }
  615.  
  616.     /**
  617.      * Retrieves the current version of EasyDiscuss
  618.      *
  619.      * @since   4.0
  620.      * @access  public
  621.      * @param   string
  622.      * @return
  623.      */
  624.     public static function getLocalVersion()
  625.     {
  626.         static $version = null;
  627.  
  628.         if (is_null($version)) {
  629.  
  630.             $manifest = DISCUSS_ADMIN_ROOT . '/easydiscuss.xml';
  631.  
  632.             $parser = JFactory::getXML($manifest, true);
  633.  
  634.             $version = (string) $parser->version;
  635.         }
  636.  
  637.         return $version;
  638.     }
  639.  
  640.     /**
  641.      * Retrieves the server's version of EasyDiscuss
  642.      *
  643.      * @since   4.0
  644.      * @access  public
  645.      * @param   string
  646.      * @return
  647.      */
  648.     public static function getVersion()
  649.     {
  650.         static $version = null;
  651.  
  652.         if (is_null($version)) {
  653.  
  654.             $connector = ED::connector();
  655.             $connector->addUrl(ED_UPDATER);
  656.             $connector->connect();
  657.  
  658.             $contents = $connector->getResult(ED_UPDATER);
  659.  
  660.             if (!$contents) {
  661.                 $version = false;
  662.  
  663.                 return $version;
  664.             }
  665.  
  666.             $obj = json_decode($contents);
  667.  
  668.             if (!$obj) {
  669.                 $version = false;
  670.  
  671.                 return $version;
  672.             }
  673.  
  674.             $version = $obj->version;
  675.         }
  676.  
  677.         return $version;
  678.     }
  679.  
  680.     /**
  681.      * Retrieves the default value from the configuration file
  682.      *
  683.      * @since   4.0
  684.      * @access  public
  685.      * @param   string
  686.      * @return
  687.      */
  688.     public static function getDefaultConfigValue($key, $defaultVal = null)
  689.     {
  690.         static $defaults = null;
  691.  
  692.         if (is_null($defaults)) {
  693.  
  694.             $file = DISCUSS_ADMIN_ROOT . '/defaults/configuration.ini';
  695.             $contents = JFile::read($file);
  696.  
  697.             $defaults = new JRegistry($contents);
  698.         }
  699.  
  700.         return $defaults->get($key, $defaultVal);
  701.     }
  702.  
  703.     /**
  704.      * Retrieves the core configuration object for EasyDiscuss.
  705.      *
  706.      * @since   1.0
  707.      * @access  public
  708.      * @param   null
  709.      * @return  JRegistry
  710.      */
  711.     public static function config()
  712.     {
  713.         if (defined('ED_CLI')) {
  714.             return false;
  715.         }
  716.  
  717.         static $config = null;
  718.  
  719.         if (is_null($config)) {
  720.  
  721.             // Render the data from the ini first.
  722.             $raw = JFile::read(DISCUSS_ADMIN_ROOT . '/defaults/configuration.ini');
  723.  
  724.             $config = ED::getRegistry($raw);
  725.  
  726.             // Retrieve the data from the db
  727.             $db = ED::db();
  728.             $query = 'SELECT ' . $db->qn('params') . ' FROM ' . $db->qn('#__discuss_configs');
  729.             $query .= 'WHERE ' . $db->qn('name') . '=' . $db->Quote('config');
  730.  
  731.             $db->setQuery($query);
  732.             $result = $db->loadResult();
  733.  
  734.             $config->loadString($result, 'INI');
  735.         }
  736.  
  737.         return $config;
  738.     }
  739.  
  740.     public static function getPostAccess( DiscussPost $post , DiscussCategory $category )
  741.     {
  742.         static $access  = null;
  743.  
  744.         if( is_null( $access[ $post->id ] ) )
  745.         {
  746.             // Load default ini data first
  747.             $access[ $post->id ] = new DiscussPostAccess( $post , $category);
  748.         }
  749.  
  750.         return $access[ $post->id ];
  751.     }
  752.  
  753.     /*
  754.      * Method used to determine whether the user a guest or logged in user.
  755.      * return : boolean
  756.      */
  757.     public static function isLoggedIn()
  758.     {
  759.         $my = JFactory::getUser();
  760.         $loggedIn   = (empty($my) || $my->id == 0) ? false : true;
  761.         return $loggedIn;
  762.     }
  763.  
  764.     public static function isSiteAdmin($userId = null)
  765.     {
  766.         static  $loaded = array();
  767.  
  768.         $sig    = is_null($userId) ? 'me' : $userId ;
  769.  
  770.         if(! isset( $loaded[$sig] ) )
  771.         {
  772.             $my = JFactory::getUser( $userId );
  773.  
  774.             $admin = false;
  775.             if(DiscussHelper::getJoomlaVersion() >= '1.6')
  776.             {
  777.                 $admin  = $my->authorise('core.admin');
  778.             }
  779.             else
  780.             {
  781.                 $admin  = $my->usertype == 'Super Administrator' || $my->usertype == 'Administrator' ? true : false;
  782.             }
  783.  
  784.             $loaded[ $sig ] = $admin;
  785.         }
  786.  
  787.         return $loaded[ $sig ];
  788.     }
  789.  
  790.     public static function isMine($uid)
  791.     {
  792.         $my = JFactory::getUser();
  793.  
  794.         if($my->id == 0)
  795.             return false;
  796.  
  797.         if( empty($uid) )
  798.             return false;
  799.  
  800.         $mine   = $my->id == $uid ? 1 : 0;
  801.         return $mine;
  802.     }
  803.  
  804.     public static function getUserId( $username )
  805.     {
  806.         static $userids = array();
  807.  
  808.         if( !isset( $userids[ $username ] ) || empty($userids[$username]) )
  809.         {
  810.             $db     = DiscussHelper::getDBO();
  811.  
  812.             // first get from user alias
  813.             $query  = 'SELECT `id` FROm `#__discuss_users` WHERE `alias` = ' . $db->quote( $username );
  814.             $db->setQuery( $query );
  815.             $userid = $db->loadResult();
  816.  
  817.             // then get from user nickname
  818.             if (!$userid) {
  819.                 $query  = 'SELECT `id` FROm `#__discuss_users` WHERE `nickname` = ' . $db->quote( $username );
  820.                 $db->setQuery( $query );
  821.                 $userid = $db->loadResult();
  822.             }
  823.  
  824.             // then get from username
  825.             if (!$userid) {
  826.                 $query  = 'SELECT `id` FROM `#__users` WHERE `username`=' . $db->quote( $username );
  827.                 $db->setQuery( $query );
  828.  
  829.                 $userid = $db->loadResult();
  830.             }
  831.  
  832.             if (!$userid) {
  833.                 $query  = 'SELECT `id` FROM `#__users` WHERE `name`=' . $db->quote( $username );
  834.                 $db->setQuery( $query );
  835.  
  836.                 $userid = $db->loadResult();
  837.             }
  838.  
  839.  
  840.  
  841.             $userids[$username] = $userid;
  842.         }
  843.  
  844.         return $userids[$username];
  845.     }
  846.  
  847.     public static function getAjaxURL()
  848.     {
  849.         $uri        = JFactory::getURI();
  850.         $language   = $uri->getVar('lang', 'none');
  851.         $app        = JFactory::getApplication();
  852.         $config     = DiscussHelper::getJConfig();
  853.         $router     = $app->getRouter();
  854.         $url        = rtrim( JURI::base() , '/' );
  855.  
  856.         $url        = $url . '/index.php?option=com_easydiscuss&lang=' . $language;
  857.  
  858.         if( $router->getMode() == JROUTER_MODE_SEF && JPluginHelper::isEnabled("system","languagefilter") )
  859.         {
  860.             $rewrite    = $config->get('sef_rewrite');
  861.  
  862.             $base       = str_ireplace( JURI::root( true ) , '' , $uri->getPath() );
  863.             $path       =  $rewrite ? $base : JString::substr( $base , 10 );
  864.             $path       = JString::trim( $path , '/' );
  865.             $parts      = explode( '/' , $path );
  866.  
  867.             $language = addslashes($language);
  868.  
  869.             if($parts) {
  870.                 // First segment will always be the language filter.
  871.                 $language   = reset( $parts );
  872.             } else {
  873.                 $language   = 'none';
  874.             }
  875.  
  876.             if ($rewrite) {
  877.                 $url        = rtrim( JURI::root() , '/' ) . '/' . $language . '/?option=com_easydiscuss';
  878.                 $language   = 'none';
  879.             } else {
  880.                 $url        = rtrim( JURI::root() , '/' ) . '/index.php/' . $language . '/?option=com_easydiscuss';
  881.             }
  882.         }
  883.  
  884.         return $url;
  885.     }
  886.  
  887.     public static function getBaseUrl()
  888.     {
  889.         static $url;
  890.  
  891.         if (isset($url)) return $url;
  892.  
  893.         if( DiscussHelper::getJoomlaVersion() >= '1.6' )
  894.         {
  895.             $uri        = JFactory::getURI();
  896.             $language   = $uri->getVar( 'lang' , 'none' );
  897.             $app        = JFactory::getApplication();
  898.             $config     = DiscussHelper::getJConfig();
  899.             $router     = $app->getRouter();
  900.             $url        = rtrim( JURI::base() , '/' );
  901.  
  902.             $url        = $url . '/index.php?option=com_easydiscuss&lang=' . $language;
  903.  
  904.             if( $router->getMode() == JROUTER_MODE_SEF && JPluginHelper::isEnabled("system","languagefilter") )
  905.             {
  906.                 $rewrite    = $config->get('sef_rewrite');
  907.  
  908.                 $base       = str_ireplace( JURI::root( true ) , '' , $uri->getPath() );
  909.                 $path       =  $rewrite ? $base : JString::substr( $base , 10 );
  910.                 $path       = JString::trim( $path , '/' );
  911.                 $parts      = explode( '/' , $path );
  912.  
  913.                 if( $parts )
  914.                 {
  915.                     // First segment will always be the language filter.
  916.                     $language   = reset( $parts );
  917.                 }
  918.                 else
  919.                 {
  920.                     $language   = 'none';
  921.                 }
  922.  
  923.                 if( $rewrite )
  924.                 {
  925.                     $url        = rtrim( JURI::root() , '/' ) . '/' . $language . '/?option=com_easydiscuss';
  926.                     $language   = 'none';
  927.                 }
  928.                 else
  929.                 {
  930.                     $url        = rtrim( JURI::root() , '/' ) . '/index.php/' . $language . '/?option=com_easydiscuss';
  931.                 }
  932.             }
  933.         }
  934.         else
  935.         {
  936.  
  937.             $url        = rtrim( JURI::root() , '/' ) . '/index.php?option=com_easydiscuss';
  938.         }
  939.  
  940.         $menu = JFactory::getApplication()->getmenu();
  941.  
  942.         if( !empty($menu) )
  943.         {
  944.             $item = $menu->getActive();
  945.             if( isset( $item->id) )
  946.             {
  947.                 $url    .= '&Itemid=' . $item->id;
  948.             }
  949.         }
  950.  
  951.         // Some SEF components tries to do a 301 redirect from non-www prefix to www prefix.
  952.         // Need to sort them out here.
  953.         $currentURL     = isset( $_SERVER[ 'HTTP_HOST' ] ) ? $_SERVER[ 'HTTP_HOST' ] : '';
  954.  
  955.         if( !empty( $currentURL ) )
  956.         {
  957.             // When the url contains www and the current accessed url does not contain www, fix it.
  958.             if( stristr($currentURL , 'www' ) === false && stristr( $url , 'www') !== false )
  959.             {
  960.                 $url    = str_ireplace( 'www.' , '' , $url );
  961.             }
  962.  
  963.             // When the url does not contain www and the current accessed url contains www.
  964.             if( stristr( $currentURL , 'www' ) !== false && stristr( $url , 'www') === false )
  965.             {
  966.                 $url    = str_ireplace( '://' , '://www.' , $url );
  967.             }
  968.         }
  969.  
  970.         return $url;
  971.     }
  972.  
  973.     /**
  974.      * Loads the default languages for EasyDiscuss
  975.      *
  976.      * @since   4.0
  977.      * @access  public
  978.      * @param   string
  979.      * @return
  980.      */
  981.     public static function loadLanguages($path = JPATH_ROOT)
  982.     {
  983.         static $loaded = array();
  984.  
  985.         if (!isset($loaded[$path])) {
  986.             $lang = JFactory::getLanguage();
  987.  
  988.             // Load site's default language file.
  989.             $lang->load('com_easydiscuss', $path);
  990.  
  991.             $loaded[$path] = true;
  992.         }
  993.  
  994.         return $loaded[$path];
  995.     }
  996.  
  997.     public static function getDurationString($dateTimeDiffObj)
  998.     {
  999.         $lang = JFactory::getLanguage();
  1000.         $lang->load('com_easydiscuss', JPATH_ROOT);
  1001.  
  1002.         $data = $dateTimeDiffObj;
  1003.         $returnStr = '';
  1004.  
  1005.         if ($data->daydiff <= 0) {
  1006.             $timeDate = explode(':', $data->timediff);
  1007.  
  1008.             // ensure all has a colon
  1009.             if (!isset($timeDate[1])) {
  1010.                 $timeDate[1] = null;
  1011.             }
  1012.  
  1013.             if (intval($timeDate[0], 10) >= 1) {
  1014.                 $returnStr = ED::string()->getNoun('COM_EASYDISCUSS_HOURS_AGO', intval($timeDate[0], 10), true);
  1015.  
  1016.             } else if(intval($timeDate[1], 10) >= 2) {
  1017.                 $returnStr = ED::string()->getNoun('COM_EASYDISCUSS_MINUTES_AGO', intval($timeDate[1], 10), true);
  1018.  
  1019.             } else {
  1020.                 $returnStr = JText::_('COM_EASYDISCUSS_LESS_THAN_A_MINUTE_AGO');
  1021.             }
  1022.  
  1023.         } else if (($data->daydiff >= 1) && ($data->daydiff < 7)) {
  1024.             $returnStr = ED::string()->getNoun('COM_EASYDISCUSS_DAYS_AGO', $data->daydiff, true);
  1025.  
  1026.         } else if ($data->daydiff >= 7 && $data->daydiff <= 30) {
  1027.             $returnStr = (intval($data->daydiff/7, 10) == 1 ? JText::_('COM_EASYDISCUSS_ONE_WEEK_AGO') : JText::sprintf('COM_EASYDISCUSS_WEEKS_AGO', intval($data->daydiff/7, 10)));
  1028.  
  1029.         } else {
  1030.             $returnStr = JText::_('COM_EASYDISCUSS_MORE_THAN_A_MONTH_AGO');
  1031.         }
  1032.  
  1033.         return $returnStr;
  1034.     }
  1035.  
  1036.     public static function storeSession($data, $key, $ns = 'com_easydiscuss')
  1037.     {
  1038.         $mySess = JFactory::getSession();
  1039.         $mySess->set($key, $data, $ns);
  1040.     }
  1041.  
  1042.     public static function getSession($key, $ns = 'com_easydiscuss')
  1043.     {
  1044.         $data = null;
  1045.  
  1046.         $mySess = JFactory::getSession();
  1047.         if($mySess->has($key, $ns))
  1048.         {
  1049.             $data = $mySess->get($key, '', $ns);
  1050.             $mySess->clear($key, $ns);
  1051.             return $data;
  1052.         }
  1053.         else
  1054.         {
  1055.             return $data;
  1056.         }
  1057.     }
  1058.  
  1059.     public static function isNew( $noofdays )
  1060.     {
  1061.         $config = DiscussHelper::getConfig();
  1062.         $isNew  = ($noofdays <= $config->get('layout_daystostaynew', 7)) ? true : false;
  1063.  
  1064.         return $isNew;
  1065.     }
  1066.  
  1067.     public static function getExternalLink($link)
  1068.     {
  1069.         $uri = JURI::getInstance();
  1070.         $domain = $uri->toString(array('scheme', 'host', 'port'));
  1071.  
  1072.         return $domain . '/' . ltrim(EDR::_($link, false), '/');
  1073.     }
  1074.  
  1075.     public static function uploadAvatar($profile, $isFromBackend = false)
  1076.     {
  1077.         jimport('joomla.utilities.error');
  1078.         jimport('joomla.filesystem.file');
  1079.         jimport('joomla.filesystem.folder');
  1080.  
  1081.         $my = JFactory::getUser();
  1082.         $mainframe = JFactory::getApplication();
  1083.         $config = ED::config();
  1084.  
  1085.         $avatar_config_path = $config->get('main_avatarpath');
  1086.         $avatar_config_path = rtrim($avatar_config_path, '/');
  1087.         $avatar_config_path = JString::str_ireplace('/', DIRECTORY_SEPARATOR, $avatar_config_path);
  1088.  
  1089.         // Get the upload path
  1090.         $upload_path = JPATH_ROOT . '/' . $avatar_config_path;
  1091.         $rel_upload_path = $avatar_config_path;
  1092.  
  1093.         $error = null;
  1094.         $file = JRequest::getVar('Filedata', '', 'files', 'array');
  1095.  
  1096.         // Check whether the upload folder exist or not. if not create it.
  1097.         if (!JFolder::exists($upload_path)) {
  1098.             if (!JFolder::create($upload_path)) {
  1099.                 // Redirect
  1100.                 if (!$isFromBackend) {
  1101.                     ED::setMessageQueue(JText::_( 'COM_EASYDISCUSS_FAILED_TO_CREATE_UPLOAD_FOLDER' ), 'error');
  1102.                     $mainframe->redirect( EDR::_('index.php?option=com_easydiscuss&view=profile', false));
  1103.                     return;
  1104.                 }
  1105.  
  1106.                 // From backend
  1107.                 $mainframe->redirect( EDR::_('index.php?option=com_easydiscuss&view=users', false), JText::_('COM_EASYDISCUSS_FAILED_TO_CREATE_UPLOAD_FOLDER'), 'error');
  1108.                 return;
  1109.             }
  1110.         }
  1111.  
  1112.         // Makesafe on the file
  1113.         $date = ED::date();
  1114.         $file_ext = ED::Image()->getFileExtention($file['name']);
  1115.         $file['name'] = $my->id . '_' . JFile::makeSafe(md5($file['name'].$date->toSql())) . '.' . strtolower($file_ext);
  1116.  
  1117.  
  1118.         if (isset($file['name'])) {
  1119.             $target_file_path = $upload_path;
  1120.             $relative_target_file = $rel_upload_path . '/' . $file['name'];
  1121.             $target_file = JPath::clean($target_file_path . '/' . JFile::makeSafe($file['name']));
  1122.             $original = JPath::clean($target_file_path . '/' . 'original_' . JFile::makeSafe($file['name']));
  1123.  
  1124.             $isNew = false;
  1125.  
  1126.             if (!ED::Image()->canUpload($file, $error)) {
  1127.                 if (!$isFromBackend) {
  1128.                     ED::setMessageQueue(JText::_($error), 'error');
  1129.                     $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=profile&layout=edit', false));
  1130.                     return;
  1131.                 }
  1132.  
  1133.                 $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=users', false), JText::_($error), 'error');
  1134.  
  1135.                 return;
  1136.             }
  1137.  
  1138.             if ((int)$file['error'] != 0) {
  1139.                 if (!$isFromBackend) {
  1140.                     ED::setMessageQueue( $file['error'] , 'error');
  1141.                     $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=profile&layout=edit', false));
  1142.                     return;
  1143.                 }
  1144.                 //from backend
  1145.                 $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=users', false), $file['error'], 'error');
  1146.  
  1147.                 return;
  1148.             }
  1149.  
  1150.             //rename the file 1st.
  1151.             $oldAvatar = $profile->avatar;
  1152.             $tempAvatar = '';
  1153.             $isNew = ($oldAvatar == 'default.png')? true : false ;
  1154.  
  1155.             if (!$isNew) {
  1156.                 $session = JFactory::getSession();
  1157.                 $sessionId = $session->getToken();
  1158.  
  1159.                 $fileExt = JFile::getExt(JPath::clean($target_file_path . '/' . $oldAvatar));
  1160.                 $tempAvatar = JPath::clean($target_file_path . '/' . $sessionId . '.' . $fileExt);
  1161.  
  1162.                 // Test if old original file exists. If exist, remove it.
  1163.                 if (JFile::exists($target_file_path . '/original_' . $oldAvatar)) {
  1164.                     JFile::delete($target_file_path . '/original_' . $oldAvatar);
  1165.                 }
  1166.  
  1167.                 JFile::move($target_file_path . '/' . $oldAvatar, $tempAvatar);
  1168.             }
  1169.  
  1170.             if (JFile::exists($target_file) || JFolder::exists($target_file)) {
  1171.                 if (!$isNew) {
  1172.                     //rename back to the previous one.
  1173.                     JFile::move($tempAvatar, $target_file_path . '/' . $oldAvatar);
  1174.                 }
  1175.  
  1176.                 if (!$isFromBackend) {
  1177.                     DiscussHelper::setMessageQueue( JText::sprintf('COM_EASYDISCUSS_FILE_ALREADY_EXISTS', $relative_target_file) , 'error');
  1178.                     $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=profile', false));
  1179.                     return;
  1180.                 }
  1181.  
  1182.                 //from backend
  1183.                 $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=users', false), JText::sprintf('COM_EASYDISCUSS_FILE_ALREADY_EXISTS', $relative_target_file), 'error');
  1184.                 return;
  1185.             }
  1186.  
  1187.             // image size should be in ratio of 1:1
  1188.             $configImageWidth = $config->get('layout_avatarwidth', 160);
  1189.             $configImageHeight = $configImageWidth;
  1190.             $originalImageWidth = $config->get('layout_originalavatarwidth', 400);
  1191.             $originalImageHeight = $originalImageWidth;
  1192.  
  1193.             // Copy the original image files over
  1194.             $image = ED::simpleimage();
  1195.             $image->load($file['tmp_name']);
  1196.  
  1197.             //$image->resizeToFill( $originalImageWidth , $originalImageHeight );
  1198.  
  1199.             // By Kevin Lankhorst
  1200.             $image->resizeOriginal($originalImageWidth, $originalImageHeight, $configImageWidth, $configImageHeight);
  1201.  
  1202.             $image->save($original, $image->image_type);
  1203.             unset($image);
  1204.  
  1205.             $image = ED::simpleimage();
  1206.             $image->load($file['tmp_name']);
  1207.             $image->resizeToFill($configImageWidth, $configImageHeight);
  1208.             $image->save($target_file, $image->image_type);
  1209.  
  1210.             //now we update the user avatar. If needed, we remove the old avatar.
  1211.             if (!$isNew) {
  1212.                 if (JFile::exists($tempAvatar)) {
  1213.                     JFile::delete($tempAvatar);
  1214.                 }
  1215.             }
  1216.  
  1217.             return JFile::makeSafe($file['name']);
  1218.         } else {
  1219.             return 'default.png';
  1220.         }
  1221.  
  1222.     }
  1223.  
  1224.     public static function uploadCategoryAvatar( $category, $isFromBackend = false )
  1225.     {
  1226.         return ED::uploadMediaAvatar( 'category', $category, $isFromBackend);
  1227.     }
  1228.  
  1229.     public static function uploadMediaAvatar($mediaType, $mediaTable, $isFromBackend = false)
  1230.     {
  1231.         jimport('joomla.utilities.error');
  1232.         jimport('joomla.filesystem.file');
  1233.         jimport('joomla.filesystem.folder');
  1234.  
  1235.         $my = JFactory::getUser();
  1236.         $mainframe = JFactory::getApplication();
  1237.         $config = ED::getConfig();
  1238.  
  1239.         // required params
  1240.         $layout_type = ($mediaType == 'category') ? 'categories' : 'teamblogs';
  1241.         $view_type = ($mediaType == 'category') ? 'categories' : 'teamblogs';
  1242.         $default_avatar_type = ($mediaType == 'category') ? 'default_category.png' : 'default_team.png';
  1243.  
  1244.         if (!$isFromBackend && $mediaType == 'category') {
  1245.             $url = 'index.php?option=com_easydiscuss&view=categories';
  1246.             ED::setMessage(JText::_('COM_EASYDISCUSS_NO_PERMISSION_TO_UPLOAD_AVATAR') , 'warning');
  1247.             $mainframe->redirect(EDR::_($url, false));
  1248.         }
  1249.  
  1250.         $avatar_config_path = ($mediaType == 'category') ? $config->get('main_categoryavatarpath') : $config->get('main_teamavatarpath');
  1251.         $avatar_config_path = rtrim($avatar_config_path, '/');
  1252.         $avatar_config_path = str_replace('/', DIRECTORY_SEPARATOR, $avatar_config_path);
  1253.  
  1254.         $upload_path = JPATH_ROOT . '/' . $avatar_config_path;
  1255.         $rel_upload_path = $avatar_config_path;
  1256.  
  1257.         $err = null;
  1258.         $file = JRequest::getVar('Filedata', '', 'files', 'array');
  1259.  
  1260.         //check whether the upload folder exist or not. if not create it.
  1261.         if (!JFolder::exists($upload_path)) {
  1262.             if (!JFolder::create($upload_path)) {
  1263.                 // Redirect
  1264.                 if(!$isFromBackend) {
  1265.                     ED::setMessage(JText::_('COM_EASYDISCUSS_IMAGE_UPLOADER_FAILED_TO_CREATE_UPLOAD_FOLDER') , 'error');
  1266.                     $this->setRedirect(EDR::_('index.php?option=com_easydiscuss&view=categories', false));
  1267.                 } else {
  1268.                     //from backend
  1269.                     $this->setRedirect(EDR::_('index.php?option=com_easydiscuss&view=categories', false), JText::_('COM_EASYDISCUSS_IMAGE_UPLOADER_FAILED_TO_CREATE_UPLOAD_FOLDER'), 'error');
  1270.                 }
  1271.                 return;
  1272.             } else {
  1273.                 // folder created. now copy index.html into this folder.
  1274.                 if (!JFile::exists( $upload_path . '/index.html')) {
  1275.                     $targetFile = DISCUSS_ROOT . '/index.html';
  1276.                     $destFile = $upload_path . '/index.html';
  1277.  
  1278.                     if(JFile::exists($targetFile))
  1279.                         JFile::copy($targetFile, $destFile);
  1280.                 }
  1281.             }
  1282.         }
  1283.  
  1284.         //makesafe on the file
  1285.         $file['name'] = $mediaTable->id . '_' . JFile::makeSafe($file['name']);
  1286.  
  1287.         if (isset($file['name'])) {
  1288.             $target_file_path = $upload_path;
  1289.             $relative_target_file = $rel_upload_path . '/' . $file['name'];
  1290.             $target_file = JPath::clean($target_file_path . '/' . JFile::makeSafe($file['name']));
  1291.             $isNew = false;
  1292.  
  1293.             require_once(__DIR__ . '/image/image.php');
  1294.             require_once(__DIR__ . '/simpleimage/simpleimage.php');
  1295.  
  1296.             if (!EasyDiscussImage::canUpload($file, $err)) {
  1297.                 if(!$isFromBackend) {
  1298.                     ED::setMessage( JText::_($err), 'error');
  1299.                     $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=categories', false));
  1300.                 } else {
  1301.                     // From backend
  1302.                     $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=categories'), JText::_($err), 'error');
  1303.                 }
  1304.                 return;
  1305.             }
  1306.  
  1307.             if (0 != (int)$file['error']) {
  1308.                 if (!$isFromBackend) {
  1309.                     ED::setMessage($file['error'], 'error');
  1310.                     $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=categories', false));
  1311.                 } else {
  1312.                     // From backend
  1313.                     $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=categories', false), $file['error'], 'error');
  1314.                 }
  1315.                 return;
  1316.             }
  1317.  
  1318.             // Rename the file 1st.
  1319.             $oldAvatar = (empty($mediaTable->avatar)) ? $default_avatar_type : $mediaTable->avatar;
  1320.             $tempAvatar = '';
  1321.             if ($oldAvatar != $default_avatar_type) {
  1322.                 $session = JFactory::getSession();
  1323.                 $sessionId = $session->getToken();
  1324.  
  1325.                 $fileExt = JFile::getExt(JPath::clean($target_file_path . '/' . $oldAvatar));
  1326.                 $tempAvatar = JPath::clean($target_file_path . '/' . $sessionId . '.' . $fileExt);
  1327.  
  1328.                 JFile::move($target_file_path . '/' . $oldAvatar, $tempAvatar);
  1329.             } else {
  1330.                 $isNew  = true;
  1331.             }
  1332.  
  1333.  
  1334.             if (JFile::exists($target_file)) {
  1335.                 if ($oldAvatar != $default_avatar_type) {
  1336.                     //rename back to the previous one.
  1337.                     JFile::move($tempAvatar, $target_file_path . '/' . $oldAvatar);
  1338.                 }
  1339.  
  1340.                 if (!$isFromBackend) {
  1341.                     ED::setMessage(JText::sprintf('ERROR.FILE_ALREADY_EXISTS', $relative_target_file), 'error');
  1342.                     $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=categories', false));
  1343.                 } else {
  1344.                     //from backend
  1345.                     $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=categories', false), JText::sprintf('ERROR.FILE_ALREADY_EXISTS', $relative_target_file), 'error');
  1346.                 }
  1347.                 return;
  1348.             }
  1349.  
  1350.             if (JFolder::exists($target_file)) {
  1351.  
  1352.                 if ($oldAvatar != $default_avatar_type) {
  1353.                     //rename back to the previous one.
  1354.                     JFile::move($tempAvatar, $target_file_path . '/' . $oldAvatar);
  1355.                 }
  1356.  
  1357.                 if (!$isFromBackend) {
  1358.                     //JError::raiseNotice(100, JText::sprintf('ERROR.FOLDER_ALREADY_EXISTS',$relative_target_file));
  1359.                     ED::setMessage(JText::sprintf('ERROR.FOLDER_ALREADY_EXISTS', $relative_target_file), 'error');
  1360.                     $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=categories', false));
  1361.                 } else {
  1362.                     //from backend
  1363.                     $mainframe->redirect(EDR::_('index.php?option=com_easydiscuss&view=categories', false), JText::sprintf('ERROR.FILE_ALREADY_EXISTS', $relative_target_file), 'error');
  1364.                 }
  1365.                 return;
  1366.             }
  1367.  
  1368.             $configImageWidth  = DISCUSS_AVATAR_LARGE_WIDTH;
  1369.             $configImageHeight = DISCUSS_AVATAR_LARGE_HEIGHT;
  1370.  
  1371.             $image = new EasyDiscussSimpleImage();
  1372.             $image->load($file['tmp_name']);
  1373.             $image->resize($configImageWidth, $configImageHeight);
  1374.             $image->save($target_file, $image->image_type);
  1375.  
  1376.             //now we update the user avatar. If needed, we remove the old avatar.
  1377.             if ($oldAvatar != $default_avatar_type) {
  1378.                 if (JFile::exists($tempAvatar)) {
  1379.                     JFile::delete($tempAvatar);
  1380.                 }
  1381.             }
  1382.  
  1383.             return JFile::makeSafe($file['name']);
  1384.         } else {
  1385.             return $default_avatar_type;
  1386.         }
  1387.  
  1388.     }
  1389.  
  1390.     /**
  1391.      * Applies word filtering
  1392.      *
  1393.      * @since   4.0
  1394.      * @access  public
  1395.      * @param   string
  1396.      * @return
  1397.      */
  1398.     public static function wordFilter($text)
  1399.     {
  1400.         $config = ED::Config();
  1401.  
  1402.         if (empty($text)) {
  1403.             return $text;
  1404.         }
  1405.  
  1406.         if (trim($text) == '') {
  1407.             return $text;
  1408.         }
  1409.  
  1410.         if ($config->get('main_filterbadword', 1) && $config->get('main_filtertext', '') != '') {
  1411.  
  1412.             require_once DISCUSS_HELPERS . '/filter.php';
  1413.             // filter out bad words.
  1414.             $bwFilter       = new BadWFilter();
  1415.             $textToBeFilter = explode(',', $config->get('main_filtertext'));
  1416.  
  1417.             // lets do some AI here. for each string, if there is a space,
  1418.             // remove the space and make it as a new filter text.
  1419.             if( count($textToBeFilter) > 0 )
  1420.             {
  1421.                 $newFilterSet   = array();
  1422.                 foreach( $textToBeFilter as $item)
  1423.                 {
  1424.                     if( JString::stristr($item, ' ') !== false )
  1425.                     {
  1426.                         $newKeyWord     = JString::str_ireplace(' ', '', $item);
  1427.                         $newFilterSet[] = $newKeyWord;
  1428.                     }
  1429.                 } // foreach
  1430.  
  1431.                 if( count($newFilterSet) > 0 )
  1432.                 {
  1433.                     $tmpNewFitler   = array_merge($textToBeFilter, $newFilterSet);
  1434.                     $textToBeFilter = array_unique($tmpNewFitler);
  1435.                 }
  1436.  
  1437.             }//end if
  1438.  
  1439.             $bwFilter->strings  = $textToBeFilter;
  1440.  
  1441.             //to be filtered text
  1442.             $bwFilter->text     = $text;
  1443.             $new_text           = $bwFilter->filter();
  1444.  
  1445.             $text               = $new_text;
  1446.         }
  1447.  
  1448.         return $text;
  1449.     }
  1450.  
  1451.     /**
  1452.      * Formats a discussion object
  1453.      *
  1454.      * @since   4.0
  1455.      * @access  public
  1456.      * @param   string
  1457.      * @return
  1458.      */
  1459.     public static function formatPost($rows, $isSearch = false , $isFrontpage = false)
  1460.     {
  1461.         // If there is no items, skip this altogether
  1462.         if (!$rows) {
  1463.             return $rows;
  1464.         }
  1465.  
  1466.         $posts = array();
  1467.  
  1468.         foreach ($rows as $row) {
  1469.  
  1470.             // Load it into our post library
  1471.             $post = ED::post($row);
  1472.  
  1473.             if ($isFrontpage) {
  1474.                 $model = ED::model('Posts');
  1475.                 $post->lastReply = $model->getLastReply($post->id);
  1476.             }
  1477.  
  1478.             $posts[] = $post;
  1479.         }
  1480.  
  1481.         return $posts;
  1482.     }
  1483.  
  1484.     public static function formatComments($comments)
  1485.     {
  1486.         if (!$comments) {
  1487.             return false;
  1488.         }
  1489.  
  1490.         $path = JPATH_ADMINISTRATOR . '/components/com_easydiscuss/includes/events/events.php';
  1491.  
  1492.         include_once($path);
  1493.  
  1494.         $config = ED::config();
  1495.  
  1496.         $result = array();
  1497.  
  1498.         foreach ($comments as $row) {
  1499.  
  1500.             $comment = ED::table('Comment');
  1501.             $comment->bind($row);
  1502.  
  1503.             $comment->duration = ED::date()->toLapsed($comment->modified);
  1504.  
  1505.             $creator = ED::user($comment->user_id);
  1506.             $comment->creator = $creator;
  1507.  
  1508.             if ($config->get('main_content_trigger_comments')) {
  1509.  
  1510.                 // process content plugins
  1511.                 $comment->content = $comment->comment;
  1512.  
  1513.                 EasyDiscussEvents::importPlugin('content');
  1514.                 EasyDiscussEvents::onContentPrepare('comment', $comment);
  1515.  
  1516.                 $comment->event = new stdClass();
  1517.  
  1518.                 $results = EasyDiscussEvents::onContentBeforeDisplay('comment', $comment);
  1519.                 $comment->event->beforeDisplayContent = trim(implode("\n", $results));
  1520.  
  1521.                 $results = EasyDiscussEvents::onContentAfterDisplay('comment', $comment);
  1522.                 $comment->event->afterDisplayContent = trim(implode("\n", $results));
  1523.  
  1524.                 $comment->comment = $comment->content;
  1525.                 unset($comment->content);
  1526.  
  1527.                 $comment->comment = ED::badwords()->filter($comment->comment);
  1528.             }
  1529.  
  1530.             $result[] = $comment;
  1531.         }
  1532.  
  1533.         return $result;
  1534.     }
  1535.  
  1536.     /**
  1537.      * Formats the necessary output for reply items
  1538.      *
  1539.      * @since   4.0
  1540.      * @access  public
  1541.      * @param   string
  1542.      * @return
  1543.      */
  1544.     public static function formatReplies($result, $category = null, $pagination = true, $acceptedReply = false)
  1545.     {
  1546.         $config = ED::config();
  1547.  
  1548.         if (!$result) {
  1549.             return $result;
  1550.         }
  1551.  
  1552.         $limitstart = JFactory::getApplication()->input->get('limitstart', 0);
  1553.         $replies = array();
  1554.  
  1555.         foreach ($result as $key => $row) {
  1556.             $reply = ED::post($row);
  1557.  
  1558.             $reply->permalink = EDR::getReplyRoute($reply->parent_id, $reply->id);
  1559.  
  1560.             // Default reply permalink title; specifically for accepted answer.
  1561.             $reply->seq = JText::_('COM_EASYDISCUSS_REPLY_PERMALINK_TITLE');
  1562.  
  1563.             if (!$acceptedReply) {
  1564.                 $reply->seq = $key + 1;
  1565.  
  1566.                 if ($pagination) {
  1567.                     $reply->seq = $limitstart ? $key + $limitstart + 1 : $key + 1;
  1568.                 }
  1569.             }
  1570.  
  1571.             if ($config->get('main_comment')) {
  1572.                 $commentLimit = $config->get('main_comment_pagination') ? $config->get('main_comment_pagination_count') : null;
  1573.                 $reply->comments = $reply->getComments($commentLimit);
  1574.  
  1575.                 // get post comments count
  1576.                 $reply->commentsCount = $reply->getTotalComments();
  1577.             }
  1578.  
  1579.             $replies[] = $reply;
  1580.         }
  1581.  
  1582.         return $replies;
  1583.     }
  1584.  
  1585.     public static function formatUsers( $result )
  1586.     {
  1587.         if( !$result )
  1588.         {
  1589.             return $result;
  1590.         }
  1591.  
  1592.         $total  = count( $result );
  1593.  
  1594.         $authorIds  = array();
  1595.         for( $i =0 ; $i < $total; $i++ )
  1596.         {
  1597.             $item           = $result[ $i ];
  1598.             $authorIds[]    = $item->id;
  1599.         }
  1600.  
  1601.         // Reduce SQL queries by pre-loading all author object.
  1602.         $authorIds  = array_unique($authorIds);
  1603.         ED::user($authorIds);
  1604.  
  1605.         $users  = array();
  1606.         for( $i =0 ; $i < $total; $i++ )
  1607.         {
  1608.             $row    =& $result[ $i ];
  1609.  
  1610.             $user = ED::user($row->id);
  1611.             $users[] = $user;
  1612.         }
  1613.  
  1614.         return $users;
  1615.     }
  1616.  
  1617.     public static function getVoters($id, $limit='5')
  1618.     {
  1619.         $config = DiscussHelper::getConfig();
  1620.  
  1621.         $table  = DiscussHelper::getTable( 'Post' );
  1622.         $voters = $table->getVoters($id, $limit);
  1623.  
  1624.         $data                   = new stdClass();
  1625.         $data->voters           = '';
  1626.         $data->shownVoterCount  = '';
  1627.  
  1628.         if(!empty($voters))
  1629.         {
  1630.             $data->shownVoterCount = count($voters);
  1631.  
  1632.             foreach($voters as $voter)
  1633.             {
  1634.                 $displayname = $config->get('layout_nameformat');
  1635.  
  1636.                 switch($displayname)
  1637.                 {
  1638.                     case "name" :
  1639.                         $votername = $voter->name;
  1640.                         break;
  1641.                     case "username" :
  1642.                         $votername = $voter->username;
  1643.                         break;
  1644.                     case "nickname" :
  1645.                     default :
  1646.                         $votername = (empty($voter->nickname)) ? $voter->name : $voter->nickname;
  1647.                         break;
  1648.                 }
  1649.  
  1650.                 if(!empty($data->voters))
  1651.                 {
  1652.                     $data->voters .= ', ';
  1653.                 }
  1654.  
  1655.                 $data->voters .= '<a href="' . DiscussRouter::_( 'index.php?option=com_easydiscuss&view=profile&id=' . $voter->user_id ) . '">' . $votername . '</a>';
  1656.             }
  1657.         }
  1658.  
  1659.         return $data;
  1660.     }
  1661.  
  1662.     public static function getJoomlaVersion()
  1663.     {
  1664.         $jVerArr    = explode('.', JVERSION);
  1665.         $jVersion   = $jVerArr[0] . '.' . $jVerArr[1];
  1666.  
  1667.         return $jVersion;
  1668.     }
  1669.  
  1670.     public static function isJoomla31()
  1671.     {
  1672.         return DiscussHelper::getJoomlaVersion() >= '3.1';
  1673.     }
  1674.  
  1675.     public static function isJoomla30()
  1676.     {
  1677.         return DiscussHelper::getJoomlaVersion() >= '3.0';
  1678.     }
  1679.  
  1680.     public static function isJoomla25()
  1681.     {
  1682.         return DiscussHelper::getJoomlaVersion() >= '1.6' && DiscussHelper::getJoomlaVersion() <= '2.5';
  1683.     }
  1684.  
  1685.     public static function isJoomla15()
  1686.     {
  1687.         return DiscussHelper::getJoomlaVersion() == '1.5';
  1688.     }
  1689.  
  1690.     public static function getDefaultSAIds()
  1691.     {
  1692.         $saUserId   = '62';
  1693.  
  1694.         if(DiscussHelper::getJoomlaVersion() >= '1.6')
  1695.         {
  1696.             $saUsers    = DiscussHelper::getSAUsersIds();
  1697.             $saUserId   = $saUsers[0];
  1698.         }
  1699.  
  1700.         return $saUserId;
  1701.     }
  1702.  
  1703.     /**
  1704.      * Used in J1.5!. To retrieve list of superadmin users's id.
  1705.      * array
  1706.      */
  1707.     public static function getSAUsersIds15()
  1708.     {
  1709.         $db = DiscussHelper::getDBO();
  1710.  
  1711.         $query = 'SELECT `id` FROM `#__users`';
  1712.         $query .= ' WHERE (LOWER( usertype ) = ' . $db->Quote('super administrator');
  1713.         $query .= ' OR `gid` = ' . $db->Quote('25') . ')';
  1714.         $query .= ' ORDER BY `id` ASC';
  1715.  
  1716.         $db->setQuery($query);
  1717.         $result = $db->loadResultArray();
  1718.  
  1719.         $result = (empty($result)) ? array( '62' ) : $result;
  1720.  
  1721.         return $result;
  1722.     }
  1723.  
  1724.     /**
  1725.      * Used in J1.6!. To retrieve list of superadmin users's id.
  1726.      * array
  1727.      */
  1728.     public static function getSAUsersIds()
  1729.     {
  1730.         if( ED::getJoomlaVersion() < '1.6' ) {
  1731.             return ED::getSAUsersIds15();
  1732.         }
  1733.  
  1734.         $db = DiscussHelper::getDBO();
  1735.  
  1736.         $query  = 'SELECT a.`id`, a.`title`';
  1737.         $query  .= ' FROM `#__usergroups` AS a';
  1738.         $query  .= ' LEFT JOIN `#__usergroups` AS b ON a.lft > b.lft AND a.rgt < b.rgt';
  1739.         $query  .= ' GROUP BY a.id';
  1740.         $query  .= ' ORDER BY a.lft ASC';
  1741.  
  1742.         $db->setQuery($query);
  1743.         $result = $db->loadObjectList();
  1744.  
  1745.         $saGroup    = array();
  1746.         foreach($result as $group)
  1747.         {
  1748.             if(JAccess::checkGroup($group->id, 'core.admin'))
  1749.             {
  1750.                 $saGroup[]  = $group;
  1751.             }
  1752.         }
  1753.  
  1754.         //now we got all the SA groups. Time to get the users
  1755.         $saUsers = array();
  1756.         if(count($saGroup) > 0)
  1757.         {
  1758.             foreach($saGroup as $sag)
  1759.             {
  1760.                 $userArr    = JAccess::getUsersByGroup($sag->id);
  1761.                 if(count($userArr) > 0)
  1762.                 {
  1763.                     foreach($userArr as $user)
  1764.                     {
  1765.                         $saUsers[] = $user;
  1766.                     }
  1767.                 }
  1768.             }
  1769.         }
  1770.  
  1771.         return $saUsers;
  1772.     }
  1773.  
  1774.     /**
  1775.      * Generates a html code for category selection.
  1776.      *
  1777.      * @access  public
  1778.      * @param   int     $parentId   if this option spcified, it will list the parent and all its childs categories.
  1779.      * @param   int     $userId     if this option specified, it only return categories created by this userId
  1780.      * @param   string  $outType    The output type. Currently supported links and drop down selection
  1781.      * @param   string  $eleName    The element name of this populated categeries provided the outType os dropdown selection.
  1782.      * @param   string  $default    The default selected value. If given, it used at dropdown selection (auto select)
  1783.      * @param   boolean $isWrite    Determine whether the categories list used in write new page or not.
  1784.      * @param   boolean $isPublishedOnly    If this option is true, only published categories will fetched.
  1785.      * @param   array   $exclusion  A list of excluded categories that it should not be including
  1786.      */
  1787.  
  1788.     public static function populateCategories($parentId, $userId, $outType, $eleName, $default = false, $isWrite = false, $isPublishedOnly = false, $showPrivateCat = true , $disableContainers = false , $customClass = 'form-control', $exclusion = array(), $aclType = DISCUSS_CATEGORY_ACL_ACTION_VIEW, $sorting = false)
  1789.     {
  1790.         $model = ED::model('Categories');
  1791.         $parentCat  = null;
  1792.  
  1793.         if (!empty($userId)) {
  1794.             $parentCat = $model->getParentCategories($userId, 'poster', $isPublishedOnly, $showPrivateCat, $exclusion, $aclType, $sorting);
  1795.  
  1796.         } else if (!empty($parentId)) {
  1797.             $parentCat = $model->getParentCategories($parentId, 'category', $isPublishedOnly, $showPrivateCat, $exclusion, $aclType, $sorting);
  1798.  
  1799.         } else {
  1800.             $parentCat = $model->getParentCategories('', 'all', $isPublishedOnly, $showPrivateCat, $exclusion, $aclType, $sorting);
  1801.         }
  1802.  
  1803.         // If the result == null
  1804.         if (empty($parentCat)) {
  1805.             return;
  1806.         }
  1807.  
  1808.         $ignorePrivate = false;
  1809.  
  1810.         switch($outType) {
  1811.             case 'link' :
  1812.                 $ignorePrivate = false;
  1813.                 break;
  1814.             case 'select':
  1815.             default:
  1816.                 $ignorePrivate = true;
  1817.                 break;
  1818.         }
  1819.  
  1820.         $selectACLOnly = false;
  1821.  
  1822.         if ($isWrite) {
  1823.             $ignorePrivate = false;
  1824.             $selectACLOnly = true;
  1825.         }
  1826.  
  1827.         if (!empty($parentCat)) {
  1828.  
  1829.             for ($i = 0; $i < count($parentCat); $i++) {
  1830.  
  1831.                 $parent =& $parentCat[$i];
  1832.  
  1833.                 //reset
  1834.                 $parent->childs = null;
  1835.  
  1836.                 ED::buildNestedCategories($parent->id, $parent, $ignorePrivate, $isPublishedOnly, $showPrivateCat, $selectACLOnly, $exclusion);
  1837.             }//for $i
  1838.         }//end if !empty $parentCat
  1839.  
  1840.         $formEle = '';
  1841.  
  1842.         foreach ($parentCat as $category) {
  1843.  
  1844.             $selected = ($category->id == $default) ? ' selected="selected"' : '';
  1845.  
  1846.             if ($default === false) {
  1847.                 $selected = $category->default ? ' selected="selected"' : '';
  1848.             }
  1849.  
  1850.             $style = '';
  1851.             $disabled = '';
  1852.  
  1853.             // @rule: Test if the category should just act as a container
  1854.             if ($disableContainers) {
  1855.                 $disabled = $category->container ? ' disabled="disabled"' : '';
  1856.                 $style = $disabled ? ' style="font-weight:700;"' : '';
  1857.             }
  1858.  
  1859.             $formEle .= '<option value="' . $category->id . '" ' . ' data-ed-move-post-category-id=' . $category->id . ' ' . $selected . $disabled . $style . '>' . JText::_( $category->title ) . '</option>';
  1860.  
  1861.             ED::accessNestedCategories($category, $formEle, '0', $default, $outType , '' , $disableContainers);
  1862.         }
  1863.  
  1864.         $selected = empty($default) ? ' selected="selected"' : '';
  1865.  
  1866.         $html = '';
  1867.         $html .= '<select name="' . $eleName . '" id="' . $eleName .'" class="' . $customClass . '">';
  1868.  
  1869.         if (!$isWrite)
  1870.             $html .=    '<option value="0">' . JText::_('COM_EASYDISCUSS_SELECT_PARENT_CATEGORY') . '</option>';
  1871.         else
  1872.             $html .= '<option value="0" ' . $selected . '>' . JText::_('COM_EASYDISCUSS_SELECT_CATEGORY') . '</option>';
  1873.             $html .= $formEle;
  1874.             $html .= '</select>';
  1875.  
  1876.         return $html;
  1877.     }
  1878.  
  1879.     public static function buildNestedCategories($parentId, $parent, $ignorePrivate = false, $isPublishedOnly = false, $showPrivate = true, $selectACLOnly = false, $exclusion = array())
  1880.     {
  1881.         $catsModel = ED::model('Categories');
  1882.  
  1883.         // [model:category]
  1884.         $catModel = ED::model('Category');
  1885.  
  1886.         $childs = $catsModel->getChildCategories($parentId, $isPublishedOnly, $showPrivate, $exclusion);
  1887.  
  1888.         $aclType = ( $selectACLOnly ) ? DISCUSS_CATEGORY_ACL_ACTION_SELECT : DISCUSS_CATEGORY_ACL_ACTION_VIEW;
  1889.  
  1890.         $accessibleCatsIds = ED::getAccessibleCategories($parentId, $aclType);
  1891.  
  1892.         if (!empty($childs)) {
  1893.  
  1894.             for($j = 0; $j < count($childs); $j++) {
  1895.                 $child = $childs[$j];
  1896.                 $child->count = $catModel->getTotalPostCount($child->id);
  1897.                 $child->childs = null;
  1898.  
  1899.                 if (!$ignorePrivate) {
  1900.  
  1901.                     if (count($accessibleCatsIds) > 0) {
  1902.  
  1903.                         $access = false;
  1904.  
  1905.                         foreach ($accessibleCatsIds as $canAccess) {
  1906.  
  1907.                             if ($canAccess->id == $child->id) {
  1908.                                 $access = true;
  1909.                             }
  1910.                         }
  1911.  
  1912.                         if (!$access)
  1913.                             continue;
  1914.                     } else {
  1915.                         continue;
  1916.                     }
  1917.                 }
  1918.  
  1919.                 if (!ED::buildNestedCategories($child->id, $child, $ignorePrivate, $isPublishedOnly, $showPrivate, $selectACLOnly, $exclusion)) {
  1920.                     $parent->childs[] = $child;
  1921.                 }
  1922.             }// for $j
  1923.  
  1924.             if (!empty($parent->childs)) {
  1925.                 $parent->childs = array_reverse($parent->childs);
  1926.             }
  1927.         } else {
  1928.             return false;
  1929.         }
  1930.     }
  1931.  
  1932.     public static function accessNestedCategories($arr, &$html, $deep='0', $default='0', $type='select', $linkDelimiter = '' , $disableContainers = false )
  1933.     {
  1934.         $config = DiscussHelper::getConfig();
  1935.         if(isset($arr->childs) && is_array($arr->childs))
  1936.         {
  1937.             $sup    = '<sup>|_</sup>';
  1938.             $space  = '';
  1939.             $ld     = (empty($linkDelimiter)) ? '>' : $linkDelimiter;
  1940.  
  1941.             if($type == 'select' || $type == 'list')
  1942.             {
  1943.                 $deep++;
  1944.                 for($d=0; $d < $deep; $d++)
  1945.                 {
  1946.                     $space .= '&nbsp;&nbsp;&nbsp;';
  1947.                 }
  1948.             }
  1949.  
  1950.             if($type == 'list' && !empty($arr->childs))
  1951.             {
  1952.                 $html .= '<ul>';
  1953.             }
  1954.  
  1955.             for($j  = 0; $j < count($arr->childs); $j++)
  1956.             {
  1957.                 $child  = $arr->childs[$j];
  1958.  
  1959.                 switch($type)
  1960.                 {
  1961.                     case 'select':
  1962.                         $selected    = ($child->id == $default) ? ' selected="selected"' : '';
  1963.  
  1964.                         if( !$default )
  1965.                         {
  1966.                             $selected   = $child->default ? ' selected="selected"' : '';
  1967.                         }
  1968.  
  1969.                         $disabled       = '';
  1970.                         $style          = '';
  1971.  
  1972.                         // @rule: Test if the category should just act as a container
  1973.                         if( $disableContainers )
  1974.                         {
  1975.                             $disabled   = $child->container ? ' disabled="disabled"' : '';
  1976.                             $style      = $disabled ? ' style="font-weight:700;"' : '';
  1977.                         }
  1978.  
  1979.                         $html       .= '<option value="'.$child->id.'" ' . $selected . $disabled . $style . '>' . $space . $sup . $child->title . '</option>';
  1980.                         break;
  1981.                     case 'list':
  1982.                         $expand     = !empty($child->childs)? '<span onclick="EasyDiscuss.$(this).parents(\'li:first\').toggleClass(\'expand\');">[+] </span>' : '';
  1983.                         $html       .= '<li><div>' . $space . $sup . $expand . '<a href="' . DiscussRouter::getCategoryRoute( $child->id ) . '">' . $child->title . '</a> <b>(' . $child->count . ')</b></div>';
  1984.                         break;
  1985.                     case 'listlink':
  1986.                         $str = '<li><a href="' . DiscussRouter::getCategoryRoute( $child->id ) . '">';
  1987.                         $str        .= (empty($html)) ? $child->title : $ld . '&nbsp;' . $child->title;
  1988.                         $str        .= '</a></li>';
  1989.                         $html       .= $str;
  1990.                         break;
  1991.                     default:
  1992.                         $str         = '<a href="' . DiscussRouter::getCategoryRoute( $child->id ) . '">';
  1993.                         //str           .= (empty($html)) ? $child->title : $ld . '&nbsp;' . $child->title;
  1994.                         $str        .= (empty($html)) ? $child->title : $ld . '&nbsp;' . $child->title;
  1995.                         $str        .= '</a></li>';
  1996.                         $html       .= $str;
  1997.                 }
  1998.  
  1999.                 if( !$config->get('layout_category_one_level', 0) )
  2000.                 {
  2001.                     DiscussHelper::accessNestedCategories($child, $html, $deep, $default, $type, $linkDelimiter , $disableContainers );
  2002.                 }
  2003.  
  2004.  
  2005.                 if($type == 'list')
  2006.                 {
  2007.                     $html .= '</li>';
  2008.                 }
  2009.             }
  2010.  
  2011.             if($type == 'list' && !empty($arr->childs))
  2012.             {
  2013.                 $html .= '</ul>';
  2014.             }
  2015.         }
  2016.         else
  2017.         {
  2018.             return false;
  2019.         }
  2020.     }
  2021.  
  2022.     public static function accessNestedCategoriesId($arr, &$newArr)
  2023.     {
  2024.         if(isset($arr->childs) && is_array($arr->childs))
  2025.         {
  2026.             //$modelSubscribe   = ED::model( 'Subscribe' );
  2027.             //$subscribers  = $modelSubscribe->getSiteSubscribers('instant');
  2028.  
  2029.             for($j = 0; $j < count($arr->childs); $j++)
  2030.             {
  2031.                 $child = $arr->childs[$j];
  2032.  
  2033.                 $newArr[] = $child->id;
  2034.                 DiscussHelper::accessNestedCategoriesId($child, $newArr);
  2035.             }
  2036.         }
  2037.         else
  2038.         {
  2039.             return false;
  2040.         }
  2041.     }
  2042.  
  2043.     /**
  2044.      * function to retrieve the linkage backward from a child id.
  2045.      * return the full linkage from child up to parent
  2046.      */
  2047.  
  2048.     public static function populateCategoryLinkage($childId)
  2049.     {
  2050.         $arr        = array();
  2051.         $category   = DiscussHelper::getTable( 'Category' );
  2052.         $category->load($childId);
  2053.  
  2054.         $obj        = new stdClass();
  2055.         $obj->id    = $category->id;
  2056.         $obj->title = $category->title;
  2057.         $obj->alias = $category->alias;
  2058.  
  2059.         $arr[]  = $obj;
  2060.  
  2061.         if((!empty($category->parent_id)))
  2062.         {
  2063.             DiscussHelper::accessCategoryLinkage($category->parent_id, $arr);
  2064.         }
  2065.  
  2066.         $arr    = array_reverse($arr);
  2067.         return $arr;
  2068.  
  2069.     }
  2070.  
  2071.     public static function accessCategoryLinkage($childId, &$arr)
  2072.     {
  2073.         $category   = DiscussHelper::getTable( 'Category' );
  2074.  
  2075.         $category->load($childId);
  2076.  
  2077.         $obj        = new stdClass();
  2078.         $obj->id    = $category->id;
  2079.         $obj->title = $category->title;
  2080.         $obj->alias = $category->alias;
  2081.  
  2082.         $arr[]  = $obj;
  2083.  
  2084.         if((!empty($category->parent_id)))
  2085.         {
  2086.             DiscussHelper::accessCategoryLinkage($category->parent_id, $arr);
  2087.         }
  2088.         else
  2089.         {
  2090.             return false;
  2091.         }
  2092.     }
  2093.  
  2094.     /**
  2095.      * $post - post jtable object
  2096.      * $parent - post's parent id.
  2097.      * $isNew - indicate this is a new post or not.
  2098.      */
  2099.  
  2100.     public static function sendNotification( $post, $parent = 0, $isNew, $postOwner, $prevPostStatus)
  2101.     {
  2102.         JFactory::getLanguage()->load( 'com_easydiscuss' , JPATH_ROOT );
  2103.  
  2104.         $config = DiscussHelper::getConfig();
  2105.         $notify = DiscussHelper::getNotification();
  2106.  
  2107.         $emailPostTitle = $post->title;
  2108.         $modelSubscribe     = ED::model( 'Subscribe' );
  2109.  
  2110.         //get all admin emails
  2111.         $adminEmails = array();
  2112.         $ownerEmails = array();
  2113.         $newPostOwnerEmails = array();
  2114.         $postSubscriberEmails = array();
  2115.         $participantEmails = array();
  2116.  
  2117.         $catSubscriberEmails = array();
  2118.  
  2119.         if( empty( $parent ) )
  2120.         {
  2121.             // only new post we notify admin.
  2122.             if($config->get( 'notify_admin' ))
  2123.             {
  2124.                 $admins = $notify->getAdminEmails();
  2125.  
  2126.                 if(! empty($admins))
  2127.                 {
  2128.                     foreach($admins as $admin)
  2129.                     {
  2130.                         $adminEmails[]   = $admin->email;
  2131.                     }
  2132.                 }
  2133.             }
  2134.  
  2135.             // notify post owner too when moderate is on
  2136.             if( !empty( $postOwner ) )
  2137.             {
  2138.                 $postUser               = JFactory::getUser( $postOwner );
  2139.                 $newPostOwnerEmails[]   = $postUser->email;
  2140.             }
  2141.             else
  2142.             {
  2143.                 $newPostOwnerEmails[]   = $post->poster_email;
  2144.             }
  2145.  
  2146.         }
  2147.         else
  2148.         {
  2149.             // if this is a new reply, notify post owner.
  2150.             $parentTable        = DiscussHelper::getTable( 'Post' );
  2151.             $parentTable->load( $parent );
  2152.  
  2153.             $emailPostTitle = $parentTable->title;
  2154.  
  2155.             $oriPostAuthor  = $parentTable->user_id;
  2156.  
  2157.             if( !$parentTable->user_id )
  2158.             {
  2159.                 $ownerEmails[]  = $parentTable->poster_email;
  2160.             }
  2161.             else
  2162.             {
  2163.                 $oriPostUser    = JFactory::getUser( $oriPostAuthor );
  2164.                 $ownerEmails[]  = $oriPostUser->email;
  2165.             }
  2166.         }
  2167.  
  2168.         $emailSubject   = ( empty( $parent ) ) ? JText::sprintf('COM_EASYDISCUSS_NEW_POST_ADDED', $post->id , $emailPostTitle ) : JText::sprintf( 'COM_EASYDISCUSS_NEW_REPLY_ADDED', $parent, $emailPostTitle );
  2169.         $emailTemplate  = ( empty( $parent ) ) ? 'email.subscription.site.new.php' : 'email.post.reply.new.php';
  2170.  
  2171.         //get all site's subscribers email that want to receive notification immediately
  2172.         $subscriberEmails   = array();
  2173.         $subscribers        = array();
  2174.  
  2175.  
  2176.         // @rule: Specify the default name and avatar
  2177.         $authorName             = $post->poster_name;
  2178.         $authorAvatar           = DISCUSS_JURIROOT . '/media/com_easydiscuss/images/default_avatar.png';
  2179.  
  2180.  
  2181.  
  2182.         // @rule: Only process author items that belongs to a valid user.
  2183.         if (!empty($postOwner)) {
  2184.             $user = ED::user($postOwner);
  2185.  
  2186.             $authorName         = $user->getName();
  2187.             $authorAvatar       = $user->getAvatar();
  2188.         }
  2189.  
  2190.         if( $config->get('main_sitesubscription') && ($isNew || $prevPostStatus == DISCUSS_ID_PENDING) )
  2191.         {
  2192.             $subscribers        = $modelSubscribe->getSiteSubscribers('instant','',$post->category_id);
  2193.             $postSubscribers    = $modelSubscribe->getPostSubscribers( $post->parent_id );
  2194.  
  2195.             // This was added because the user allow site wide notification (as in all subscribers should get notified) but category subscribers did not get it.
  2196.             $catSubscribers     = $modelSubscribe->getCategorySubscribers( $post->id );
  2197.  
  2198.             if(! empty($subscribers))
  2199.             {
  2200.                 foreach($subscribers as $subscriber)
  2201.                 {
  2202.                     $subscriberEmails[]   = $subscriber->email;
  2203.                 }
  2204.             }
  2205.             if(! empty($postSubscribers))
  2206.             {
  2207.                 foreach($postSubscribers as $postSubscriber)
  2208.                 {
  2209.                     $postSubscriberEmails[]   = $postSubscriber->email;
  2210.                 }
  2211.             }
  2212.             if(! empty($catSubscribers))
  2213.             {
  2214.                 foreach($catSubscribers as $catSubscriber)
  2215.                 {
  2216.                     $catSubscriberEmails[]   = $catSubscriber->email;
  2217.                 }
  2218.             }
  2219.         }
  2220.  
  2221.  
  2222.         // Notify Participants if this is a reply
  2223.         if( !empty( $parent ) && $config->get( 'notify_participants' ) && ($isNew || $prevPostStatus == DISCUSS_ID_PENDING) )
  2224.         {
  2225.             $participantEmails = DiscussHelper::getHelper( 'Mailer' )->_getParticipants( $post->parent_id );
  2226.  
  2227.             $participantEmails  = array_unique( $participantEmails );
  2228.  
  2229.             // merge into owneremails. dirty hacks.
  2230.             if( count( $participantEmails ) > 0 )
  2231.             {
  2232.                 $newPostOwnerEmails = array_merge( $newPostOwnerEmails, $participantEmails );
  2233.             }
  2234.         }
  2235.  
  2236.  
  2237.         if( !empty( $adminEmails ) || !empty( $subscriberEmails ) || !empty( $newPostOwnerEmails ) || !empty( $postSubscriberEmails ) || $config->get( 'notify_all' ) )
  2238.         {
  2239.             $emails = array_unique(array_merge($adminEmails, $subscriberEmails, $newPostOwnerEmails, $postSubscriberEmails, $catSubscriberEmails));
  2240.  
  2241.             // prepare email content and information.
  2242.             $emailData                      = array();
  2243.             $emailData['postTitle']         = $emailPostTitle;
  2244.             $emailData['postAuthor']        = $authorName;
  2245.             $emailData['postAuthorAvatar']  = $authorAvatar;
  2246.             $emailData['replyAuthor']       = $authorName;
  2247.             $emailData['replyAuthorAvatar'] = $authorAvatar;
  2248.             $emailData['comment']           = $post->content;
  2249.             $emailData['postContent' ]      = $post->trimEmail( $post->content );
  2250.             $emailData['replyContent']      = $post->trimEmail( $post->content );
  2251.  
  2252.             $attachments    = $post->getAttachments();
  2253.             $emailData['attachments']   = $attachments;
  2254.  
  2255.             // get the correct post id in url, the parent post id should take precedence
  2256.             $postId = empty( $parent ) ? $post->id : $parentTable->id;
  2257.  
  2258.             $emailData['postLink']      = DiscussRouter::getRoutedURL('index.php?option=com_easydiscuss&view=post&id=' . $postId, false, true);
  2259.  
  2260.             if( $config->get( 'notify_all' ) && $post->published == DISCUSS_ID_PUBLISHED )
  2261.             {
  2262.                 $emailData['emailTemplate'] = 'email.subscription.site.new.php';
  2263.                 $emailData['emailSubject']  = JText::sprintf('COM_EASYDISCUSS_NEW_QUESTION_ASKED', $post->id , $post->title);
  2264.                 DiscussHelper::getHelper( 'Mailer' )->notifyAllMembers( $emailData, $newPostOwnerEmails );
  2265.             }
  2266.             else
  2267.             {
  2268.                 //insert into mailqueue
  2269.                 foreach ($emails as $email)
  2270.                 {
  2271.  
  2272.                     if ( in_array($email, $subscriberEmails) || in_array($email, $postSubscriberEmails) || in_array($email, $newPostOwnerEmails) )
  2273.                     {
  2274.                         $doContinue = false;
  2275.  
  2276.                         // these are subscribers
  2277.                         if (!empty($subscribers))
  2278.                         {
  2279.                             foreach ($subscribers as $key => $value)
  2280.                             {
  2281.                                 if ($value->email == $email)
  2282.                                 {
  2283.                                     $emailData['unsubscribeLink']   = DiscussHelper::getUnsubscribeLink( $subscribers[$key], true, true);
  2284.                                     $notify->addQueue($email, $emailSubject, '', $emailTemplate, $emailData);
  2285.                                     $doContinue = true;
  2286.                                     break;
  2287.                                 }
  2288.                             }
  2289.                         }
  2290.  
  2291.                         if( $doContinue )
  2292.                             continue;
  2293.  
  2294.                         if (!empty($postSubscribers))
  2295.                         {
  2296.  
  2297.                             foreach ($postSubscribers as $key => $value)
  2298.                             {
  2299.                                 if ($value->email == $email)
  2300.                                 {
  2301.  
  2302.                                     $emailData['unsubscribeLink']   = DiscussHelper::getUnsubscribeLink( $postSubscribers[$key], true, true);
  2303.                                     $notify->addQueue($email, $emailSubject, '', $emailTemplate, $emailData);
  2304.                                     $doContinue = true;
  2305.                                     break;
  2306.                                 }
  2307.                             }
  2308.                         }
  2309.  
  2310.                         if( $doContinue )
  2311.                             continue;
  2312.  
  2313.  
  2314.                         if (!empty($newPostOwnerEmails))
  2315.                         {
  2316.  
  2317.                             $emailSubject = JText::sprintf( 'COM_EASYDISCUSS_NEW_POST_ADDED', $emailPostTitle, $post->id );
  2318.  
  2319.                             foreach ($newPostOwnerEmails as $ownerEmail)
  2320.                             {
  2321.  
  2322.                                 //$emailData['unsubscribeLink'] = DiscussHelper::getUnsubscribeLink( $ownerEmail, true, true);
  2323.                                 $notify->addQueue($email, $emailSubject, '', $emailTemplate, $emailData);
  2324.                                 $doContinue = true;
  2325.                                 break;
  2326.                             }
  2327.                         }
  2328.  
  2329.                     }
  2330.                     else
  2331.                     {
  2332.  
  2333.                         // non-subscribers will not get the unsubscribe link
  2334.                         $notify->addQueue($email, $emailSubject, '', $emailTemplate, $emailData);
  2335.                     }
  2336.                 }
  2337.             }
  2338.         }
  2339.     }
  2340.  
  2341.     public static function getUserRepliesHTML( $postId, $excludeLastReplyUser   = false)
  2342.     {
  2343.         $model      = ED::model( 'Posts' );
  2344.         $replies    = $model->getUserReplies($postId, $excludeLastReplyUser);
  2345.  
  2346.         $html = '';
  2347.         if( !empty( $replies ) )
  2348.         {
  2349.             $tpl    = new DiscussThemes();
  2350.             $tpl->set( 'replies'    , $replies );
  2351.             $html   =  $tpl->fetch( 'main.item.replies.php' );
  2352.         }
  2353.  
  2354.         return $html;
  2355.     }
  2356.  
  2357.     public static function getUserAcceptedReplyHTML( $postId )
  2358.     {
  2359.         $model  = JED::model( 'Posts' );
  2360.         $reply  = $model->getAcceptedReply( $postId );
  2361.  
  2362.         $html   = '';
  2363.         if( ! empty( $reply ) )
  2364.         {
  2365.             $tpl    = new DiscussThemes();
  2366.             $tpl->set( 'reply'  , $reply );
  2367.             $html   =  $tpl->fetch( 'main.item.answered.php' );
  2368.         }
  2369.  
  2370.         return $html;
  2371.     }
  2372.  
  2373.     public static function isSiteSubscribed( $userId )
  2374.     {
  2375.         if( !class_exists( 'EasyDiscussModelSubscribe') )
  2376.         {
  2377.             jimport( 'joomla.application.component.model' );
  2378.             JLoader::import( 'subscribe' , DISCUSS_MODELS );
  2379.         }
  2380.         $model  = ED::model( 'Subscribe' );
  2381.  
  2382.         $user   = JFactory::getUser( $userId );
  2383.  
  2384.         $subscription = array();
  2385.         $subscription['type']   = 'site';
  2386.         $subscription['email']  = $user->email;
  2387.         $subscription['cid']    = 0;
  2388.  
  2389.         $result = $model->isSiteSubscribed( $subscription );
  2390.  
  2391.         return ( !isset($result['id']) ) ? '0' : $result['id'];
  2392.     }
  2393.  
  2394.     public static function isPostSubscribed( $userId, $postId )
  2395.     {
  2396.         $model  = ED::model( 'Subscribe' );
  2397.  
  2398.         $user   = JFactory::getUser( $userId );
  2399.  
  2400.         $subscription = array();
  2401.         $subscription['type']   = 'post';
  2402.         $subscription['userid'] = $user->id;
  2403.         $subscription['email']  = $user->email;
  2404.         $subscription['cid']    = $postId;
  2405.  
  2406.         $result = $model->isPostSubscribedEmail( $subscription );
  2407.  
  2408.         return ( !isset($result['id']) ) ? '0' : $result['id'];
  2409.     }
  2410.  
  2411.     public static function isMySubscription( $userid, $type, $subId)
  2412.     {
  2413.         $model      = ED::model( 'Subscribe' );
  2414.         return $model->isMySubscription($userid, $type, $subId);
  2415.     }
  2416.  
  2417.     public static function hasPassword( $post )
  2418.     {
  2419.         $session    = JFactory::getSession();
  2420.         $password   = $session->get( 'DISCUSSPASSWORD_' . $post->id , '' , 'com_easydiscuss' );
  2421.  
  2422.         if( $password == $post->password )
  2423.         {
  2424.             return true;
  2425.         }
  2426.         return false;
  2427.     }
  2428.  
  2429.     public static function getUserComponent()
  2430.     {
  2431.         return ( DiscussHelper::getJoomlaVersion() >= '1.6' ) ? 'com_users' : 'com_user';
  2432.     }
  2433.  
  2434.     public static function getUserComponentLoginTask()
  2435.     {
  2436.         return ( DiscussHelper::getJoomlaVersion() >= '1.6' ) ? 'user.login' : 'login';
  2437.     }
  2438.  
  2439.     public static function getAccessibleCategories( $parentId = 0, $type = DISCUSS_CATEGORY_ACL_ACTION_VIEW, $customUserId = '' )
  2440.     {
  2441.         static $accessibleCategories = array();
  2442.  
  2443.         if( !empty($customUserId) )
  2444.         {
  2445.             $my = JFactory::getUser( $customUserId );
  2446.         }
  2447.         else
  2448.         {
  2449.             $my = JFactory::getUser();
  2450.         }
  2451.  
  2452.         // $sig     = serialize( array($type, $my->id, $parentId) );
  2453.  
  2454.         $sig    = (int) $my->id . '-' . (int) $parentId . '-' . (int) $type;
  2455.  
  2456.  
  2457.         //if( !array_key_exists($sig, $accessibleCategories) )
  2458.         if(! isset( $accessibleCategories[$sig] ) )
  2459.         {
  2460.  
  2461.             $db = DiscussHelper::getDBO();
  2462.  
  2463.             $gids       = '';
  2464.             $catQuery   =   'select distinct a.`id`, a.`private`';
  2465.             $catQuery   .=  ' from `#__discuss_category` as a';
  2466.  
  2467.  
  2468.             if( $my->id == 0 )
  2469.             {
  2470.                 $catQuery   .=  ' where (a.`private` = ' . $db->Quote('0') . ' OR ';
  2471.             }
  2472.             else
  2473.             {
  2474.                 $catQuery   .=  ' where (a.`private` = ' . $db->Quote('0') . ' OR a.`private` = ' . $db->Quote('1') . ' OR ';
  2475.             }
  2476.  
  2477.  
  2478.             $gid    = array();
  2479.             $gids   = '';
  2480.  
  2481.             if( DiscussHelper::getJoomlaVersion() >= '1.6' )
  2482.             {
  2483.                 $gid    = array();
  2484.                 if( $my->id == 0 )
  2485.                 {
  2486.                     $gid    = JAccess::getGroupsByUser(0, false);
  2487.                 }
  2488.                 else
  2489.                 {
  2490.                     $gid    = JAccess::getGroupsByUser($my->id, false);
  2491.                 }
  2492.             }
  2493.             else
  2494.             {
  2495.                 $gid    = DiscussHelper::getUserGids();
  2496.             }
  2497.  
  2498.  
  2499.             if( count( $gid ) > 0 )
  2500.             {
  2501.                 foreach( $gid as $id)
  2502.                 {
  2503.                     $gids   .= ( empty($gids) ) ? $db->Quote( $id ) : ',' . $db->Quote( $id );
  2504.                 }
  2505.  
  2506.                 $catQuery   .=  '  a.`id` IN (';
  2507.                 $catQuery .= '      select b.`category_id` from `#__discuss_category_acl_map` as b';
  2508.                 $catQuery .= '          where b.`category_id` = a.`id` and b.`acl_id` = '. $db->Quote( $type );
  2509.                 $catQuery .= '          and b.`type` = ' . $db->Quote('group');
  2510.                 $catQuery .= '          and b.`content_id` IN (' . $gids . ')';
  2511.  
  2512.                 //logged in user
  2513.                 if( $my->id != 0 )
  2514.                 {
  2515.                     $catQuery .= '          union ';
  2516.                     $catQuery .= '          select b.`category_id` from `#__discuss_category_acl_map` as b';
  2517.                     $catQuery .= '              where b.`category_id` = a.`id` and b.`acl_id` = ' . $db->Quote( $type );
  2518.                     $catQuery .= '              and b.`type` = ' . $db->Quote('user');
  2519.                     $catQuery .= '              and b.`content_id` = ' . $db->Quote( $my->id );
  2520.                 }
  2521.                 $catQuery   .= ')';
  2522.  
  2523.             }
  2524.  
  2525.             $catQuery   .= ')';
  2526.             $catQuery   .= ' AND a.parent_id = ' . $db->Quote($parentId);
  2527.  
  2528.             $db->setQuery($catQuery);
  2529.             $result = $db->loadObjectList();
  2530.  
  2531.             $accessibleCategories[ $sig ] = $result;
  2532.  
  2533.         }
  2534.  
  2535.         return $accessibleCategories[ $sig ];
  2536.     }
  2537.  
  2538.     public static function getPrivateCategories( $acltype = DISCUSS_CATEGORY_ACL_ACTION_VIEW )
  2539.     {
  2540.         $db             = DiscussHelper::getDBO();
  2541.         $my             = JFactory::getUser();
  2542.         static $result  = array();
  2543.  
  2544.         $excludeCats    = array();
  2545.  
  2546.         $sig    = (int) $my->id . '-' . (int) $acltype;
  2547.  
  2548.         if(! isset( $result[ $sig ] ) )
  2549.         {
  2550.             if($my->id == 0)
  2551.             {
  2552.                 $catQuery   =   'select distinct a.`id`, a.`private`';
  2553.                 $catQuery   .=  ' from `#__discuss_category` as a';
  2554.                 $catQuery   .=  '   left join `#__discuss_category_acl_map` as b on a.`id` = b.`category_id`';
  2555.                 $catQuery   .=  '       and b.`acl_id` = ' . $db->Quote( $acltype );
  2556.                 $catQuery   .=  '       and b.`type` = ' . $db->Quote( 'group' );
  2557.                 $catQuery   .=  ' where a.`private` != ' . $db->Quote('0');
  2558.  
  2559.                 $gid    = array();
  2560.                 $gids   = '';
  2561.  
  2562.  
  2563.                 if( DiscussHelper::getJoomlaVersion() >= '1.6' )
  2564.                 {
  2565.                     // $gid = JAccess::getGroupsByUser(0, false);
  2566.  
  2567.                     $gid    = DiscussHelper::getUserGroupId($my);
  2568.                 }
  2569.                 else
  2570.                 {
  2571.                     $gid    = DiscussHelper::getUserGids();
  2572.                 }
  2573.  
  2574.                 if( count( $gid ) > 0 )
  2575.                 {
  2576.                     foreach( $gid as $id)
  2577.                     {
  2578.                         $gids   .= ( empty($gids) ) ? $db->Quote( $id ) : ',' . $db->Quote( $id );
  2579.                     }
  2580.                     $catQuery   .= ' and a.`id` NOT IN (';
  2581.                     $catQuery   .= '     SELECT c.category_id FROM `#__discuss_category_acl_map` as c ';
  2582.                     $catQuery   .= '        WHERE c.acl_id = ' .$db->Quote( $acltype );
  2583.                     $catQuery   .= '        AND c.type = ' . $db->Quote('group');
  2584.                     $catQuery   .= '        AND c.content_id IN (' . $gids . ') )';
  2585.                 }
  2586.  
  2587.                 $db->setQuery($catQuery);
  2588.                 $result = $db->loadObjectList();
  2589.             }
  2590.             else
  2591.             {
  2592.                 $result = ED::getAclCategories ( $acltype, $my->id );
  2593.             }
  2594.  
  2595.             for($i=0; $i < count($result); $i++)
  2596.             {
  2597.                 $item =& $result[$i];
  2598.                 $item->childs = null;
  2599.  
  2600.                 DiscussHelper::buildNestedCategories($item->id, $item, true);
  2601.  
  2602.                 $catIds     = array();
  2603.                 $catIds[]   = $item->id;
  2604.                 DiscussHelper::accessNestedCategoriesId($item, $catIds);
  2605.  
  2606.                 $excludeCats    = array_merge($excludeCats, $catIds);
  2607.             }
  2608.  
  2609.             $result[ $sig ] = $excludeCats;
  2610.         }
  2611.  
  2612.         return $result[ $sig ];
  2613.     }
  2614.  
  2615.     public static function getAclCategories ($type = DISCUSS_CATEGORY_ACL_ACTION_VIEW, $userId = '', $parentId = false)
  2616.     {
  2617.         static $categories = array();
  2618.  
  2619.         //$sig = serialize( array($type, $userId, $parentId) );
  2620.         $sig = (int) $type . '-' . (int) $userId . '-' . (int) $parentId;
  2621.  
  2622.         //if( !array_key_exists($sig, $categories) )
  2623.         if (!isset($categories[$sig])) {
  2624.             $db = ED::db();
  2625.             $gid = JAccess::getGroupsByUser($userId, false);
  2626.  
  2627.             if (ED::getJoomlaVersion() >= '1.6') {
  2628.                 if ($userId == '') {
  2629.                     $gid = JAccess::getGroupsByUser(0, false);
  2630.                 } else {
  2631.                     $gid = JAccess::getGroupsByUser($userId, false);
  2632.                 }
  2633.             }
  2634.  
  2635.             $gids = '';
  2636.             if (count($gid) > 0) {
  2637.                 $gids = implode( ',', $gid );
  2638.             }
  2639.  
  2640.             $query = 'select c.`id` from `#__discuss_category` as c';
  2641.             $query .= ' where not exists (';
  2642.             $query .= '     select b.`category_id` from `#__discuss_category_acl_map` as b';
  2643.             $query .= '         where b.`category_id` = c.`id` and b.`acl_id` = '. $db->Quote($type);
  2644.             $query .= '         and b.`type` = ' . $db->Quote('group');
  2645.             $query .= '         and b.`content_id` IN (' . $gids . ')';
  2646.  
  2647.             $query .= '      )';
  2648.             $query .= ' and c.`private` = ' . $db->Quote(DISCUSS_PRIVACY_ACL);
  2649.             if( $parentId !== false )
  2650.                 $query .= ' and c.`parent_id` = ' . $db->Quote($parentId);
  2651.  
  2652.             $db->setQuery($query);
  2653.  
  2654.             $categories[$sig] = $db->loadObjectList();
  2655.         }
  2656.  
  2657.         return $categories[$sig];
  2658.     }
  2659.  
  2660.     /**
  2661.      * Renders a JTable object
  2662.      *
  2663.      * @since   4.0
  2664.      * @access  public
  2665.      * @param   string
  2666.      * @return
  2667.      */
  2668.     public static function table($name, $prefix = 'Discuss', $config = array())
  2669.     {
  2670.         // Sanitize and prepare the table class name.
  2671.         $type = preg_replace('/[^A-Z0-9_\.-]/i', '', $name);
  2672.         $className = $prefix . ucfirst($type);
  2673.  
  2674.         // Only try to load the class if it doesn't already exist.
  2675.         if (!class_exists($className)) {
  2676.  
  2677.             // Search for the class file in the JTable include paths.
  2678.             $path = DISCUSS_TABLES . '/' . strtolower($type) . '.php';
  2679.  
  2680.             // Import the class file.
  2681.             include_once($path);
  2682.         }
  2683.  
  2684.         return JTable::getInstance($type, $prefix, $config);
  2685.     }
  2686.  
  2687.     /**
  2688.      * Retrieves the model
  2689.      *
  2690.      * @since   4.0
  2691.      * @access  public
  2692.      * @param   string  The model's name.
  2693.      * @return  mixed
  2694.      */
  2695.     public static function model($name)
  2696.     {
  2697.         static $models = array();
  2698.  
  2699.         $key = $name;
  2700.  
  2701.         if (!isset($models[$key])) {
  2702.  
  2703.             $file = strtolower($name) . '.php';
  2704.  
  2705.             $path = DISCUSS_MODELS . '/' . $file;
  2706.  
  2707.             if (!JFile::exists($path)) {
  2708.                 return JError::raiseWarning(500, JText::sprintf('Requested model %1$s is not found.', $file));
  2709.             }
  2710.  
  2711.             $className = 'EasyDiscussModel' . ucfirst($name);
  2712.  
  2713.             if (!class_exists($className)) {
  2714.                 require_once($path);
  2715.             }
  2716.  
  2717.             $models[$key] = new $className();
  2718.         }
  2719.  
  2720.         return $models[$key];
  2721.     }
  2722.  
  2723.     /**
  2724.      * Retrieves the pagination object
  2725.      *
  2726.      * @since   4.0
  2727.      * @access  public
  2728.      * @param   string
  2729.      * @return
  2730.      */
  2731.     public static function getPagination($total, $limitstart, $limit, $prefix = '')
  2732.     {
  2733.         static $instances;
  2734.  
  2735.         if (!isset($instances)) {
  2736.             $instances = array();
  2737.         }
  2738.  
  2739.         $signature = serialize(array($total, $limitstart, $limit, $prefix));
  2740.  
  2741.         if (empty($instances[$signature])) {
  2742.             $pagination = ED::pagination($total, $limitstart, $limit, $prefix);
  2743.  
  2744.             $instances[$signature] = $pagination;
  2745.         }
  2746.  
  2747.         return $instances[$signature];
  2748.     }
  2749.  
  2750.     /**
  2751.      * Retrieve @JUser object based on the given email address.
  2752.      *
  2753.      * @access  public
  2754.      * @param   string $email   The user's email address.
  2755.      * @return  JUser           @JUser object.
  2756.      **/
  2757.     public static function getUserByEmail( $email )
  2758.     {
  2759.         $email  = strtolower( $email );
  2760.  
  2761.         $db     = DiscussHelper::getDBO();
  2762.  
  2763.         $query  = 'SELECT ' . $db->nameQuote( 'id' ) . ' FROM '
  2764.                 . $db->nameQuote( '#__users' ) . ' '
  2765.                 . 'WHERE LOWER(' . $db->nameQuote( 'email' ) . ') = ' . $db->Quote( $email );
  2766.         $db->setQuery( $query );
  2767.         $id     = $db->loadResult();
  2768.  
  2769.         if( !$id )
  2770.         {
  2771.             return false;
  2772.         }
  2773.  
  2774.         return JFactory::getUser( $id );
  2775.     }
  2776.  
  2777.     public static function getUserGids( $userId = '' )
  2778.     {
  2779.         $userId = empty($userId) ? null : $userId;
  2780.         $user = JFactory::getUser($userId);
  2781.  
  2782.         $groups = JAccess::getGroupsByUser($user->id);
  2783.         $ids = array();
  2784.  
  2785.         foreach ($groups as $group) {
  2786.             $ids[] = $group;
  2787.         }
  2788.  
  2789.         return $ids;
  2790.     }
  2791.  
  2792.     public static function getJoomlaUserGroups( $cid = '' )
  2793.     {
  2794.         $db = DiscussHelper::getDBO();
  2795.  
  2796.         if(ED::getJoomlaVersion() >= '1.6')
  2797.         {
  2798.             $query = 'SELECT a.id, a.title AS `name`, COUNT(DISTINCT b.id) AS level';
  2799.             $query .= ' , GROUP_CONCAT(b.id SEPARATOR \',\') AS parents';
  2800.             $query .= ' FROM #__usergroups AS a';
  2801.             $query .= ' LEFT JOIN `#__usergroups` AS b ON a.lft > b.lft AND a.rgt < b.rgt';
  2802.         }
  2803.         else
  2804.         {
  2805.             $query  = 'SELECT `id`, `name`, 0 as `level` FROM ' . $db->nameQuote('#__core_acl_aro_groups') . ' a ';
  2806.         }
  2807.  
  2808.         // Condition
  2809.         $where  = array();
  2810.  
  2811.         // We need to filter out the ROOT and USER dummy records.
  2812.         if(ED::getJoomlaVersion() < '1.6')
  2813.         {
  2814.             $where[] = '(a.`id` > 17 AND a.`id` < 26)';
  2815.         }
  2816.  
  2817.         if( !empty( $cid ) )
  2818.         {
  2819.             $where[] = ' a.`id` = ' . $db->quote($cid);
  2820.         }
  2821.         $where = ( count( $where ) ? ' WHERE ' .implode( ' AND ', $where ) : '' );
  2822.  
  2823.         $query  .= $where;
  2824.  
  2825.         // Grouping and ordering
  2826.         if( ED::getJoomlaVersion() >= '1.6' )
  2827.         {
  2828.             $query  .= ' GROUP BY a.id';
  2829.             $query  .= ' ORDER BY a.lft ASC';
  2830.         }
  2831.         else
  2832.         {
  2833.             $query  .= ' ORDER BY a.id';
  2834.         }
  2835.  
  2836.         $db->setQuery( $query );
  2837.         $result = $db->loadObjectList();
  2838.  
  2839.         if( DiscussHelper::getJoomlaVersion() < '1.6' )
  2840.         {
  2841.             $guest = new stdClass();
  2842.             $guest->id      = '0';
  2843.             $guest->name    = 'Public';
  2844.             $guest->level   = '0';
  2845.             array_unshift( $result, $guest );
  2846.         }
  2847.  
  2848.         return $result;
  2849.     }
  2850.  
  2851.     public static function getUnsubscribeLink($subdata, $external = false, $html = false)
  2852.     {
  2853.         $unsubdata  = base64_encode("type=".$subdata->type."\r\nsid=".$subdata->id."\r\nuid=".$subdata->userid."\r\ntoken=".md5($subdata->id.$subdata->created));
  2854.  
  2855.         $link = EDR::getRoutedURL('index.php?option=com_easydiscuss&controller=subscription&task=unsubscribe&data='.$unsubdata, false, $external);
  2856.  
  2857.         return $link;
  2858.     }
  2859.  
  2860.     /*
  2861.      * Return class name according to user's group.
  2862.      * e.g. 'reply-usergroup-1 reply-usergroup-2'
  2863.      *
  2864.      */
  2865.     public static function userToClassname($jUserObj, $classPrefix = 'reply', $delimiter = '-')
  2866.     {
  2867.         if (is_numeric($jUserObj))
  2868.         {
  2869.             $jUserObj   = JFactory::getUser($jUserObj);
  2870.         }
  2871.  
  2872.         if( !$jUserObj instanceof JUser )
  2873.         {
  2874.             return '';
  2875.         }
  2876.  
  2877.         static $classNames;
  2878.  
  2879.         if (!isset($classNames))
  2880.         {
  2881.             $classNames = array();
  2882.         }
  2883.  
  2884.         $signature = serialize(array($jUserObj->id, $classPrefix, $delimiter));
  2885.  
  2886.         if (!isset($classNames[$signature]))
  2887.         {
  2888.             $classes    = array();
  2889.  
  2890.             $classes[]  = $classPrefix . $delimiter . 'user' . $delimiter . $jUserObj->id;
  2891.  
  2892.             if (property_exists($jUserObj, 'gid'))
  2893.             {
  2894.                 $classes[]  = $classPrefix . $delimiter . 'usergroup' . $delimiter . $jUserObj->get( 'gid' );
  2895.             }
  2896.             else
  2897.             {
  2898.                 $groups     = $jUserObj->getAuthorisedGroups();
  2899.  
  2900.                 foreach($groups as $id)
  2901.                 {
  2902.                     $classes[] = $classPrefix . $delimiter . 'usergroup' . $delimiter . $id;
  2903.                 }
  2904.             }
  2905.  
  2906.             $classNames[$signature] = implode(' ', $classes);
  2907.         }
  2908.  
  2909.         return $classNames[$signature];
  2910.     }
  2911.  
  2912.     /**
  2913.      * Ensures that the user is logged in
  2914.      *
  2915.      * @since   4.0
  2916.      * @access  public
  2917.      * @param   string
  2918.      * @return
  2919.      */
  2920.     public static function requireLogin()
  2921.     {
  2922.         $app = JFactory::getApplication();
  2923.         $user = JFactory::getUser();
  2924.  
  2925.         if ($user->guest) {
  2926.  
  2927.             // Set the callback so it can be use later.
  2928.             $currentUrl = EDR::current();
  2929.             ED::setCallback($currentUrl);
  2930.  
  2931.             ED::setMessageQueue(JText::_( 'COM_EASYDISCUSS_SIGNIN_PLEASE_LOGIN' ), 'info');
  2932.             return $app->redirect(EDR::_('view=login', false));
  2933.         }
  2934.     }
  2935.  
  2936.     /**
  2937.      * Give a proper redirection when the user does not have the permission to view the item.
  2938.      *
  2939.      * @since   4.0
  2940.      * @access  public
  2941.      * @param   string
  2942.      * @return
  2943.      */
  2944.     public static function getErrorRedirection($message = null)
  2945.     {
  2946.         $config = ED::config();
  2947.         $app = JFactory::getApplication();
  2948.         $user = JFactory::getUser();
  2949.  
  2950.         if (!$message) {
  2951.             $message = JText::_('COM_EASYDISCUSS_SYSTEM_INSUFFICIENT_PERMISSIONS');
  2952.         }
  2953.  
  2954.         $redirection = $config->get('system_error_redirection', true);
  2955.  
  2956.         if ($redirection) {
  2957.  
  2958.             // If user haven't logged in, redirect them to login page.
  2959.             ED::requireLogin();
  2960.  
  2961.             // If it reached here means the user is already logged in.
  2962.             ED::setMessageQueue($message, 'error');
  2963.             return $app->redirect(EDR::_('view=index'), false);
  2964.         }
  2965.  
  2966.         // default redirection
  2967.         return JError::raiseError(404, $message);
  2968.     }
  2969.  
  2970.     /**
  2971.      * Retrieve similar question based on the keywords
  2972.      *
  2973.      * @access  public
  2974.      * @param   string  $keywords
  2975.      */
  2976.     public static function getSimilarQuestion( $text = '' )
  2977.     {
  2978.  
  2979.         $config = ED::config();
  2980.  
  2981.         if (empty($text)) {
  2982.             return '';
  2983.         }
  2984.  
  2985.         if (! $config->get('main_similartopic', 0)){
  2986.             return '';
  2987.         }
  2988.  
  2989.  
  2990.         $options = array();
  2991.         $options['limi'] = $config->get('main_similartopic_limit', '5');
  2992.         $options['includePrivatePost'] = $config->get('main_similartopic_privatepost', 0);
  2993.  
  2994.         $model = ED::model('Posts');
  2995.         $posts = $model->getSimilarQuestion($text, $options);
  2996.  
  2997.         if ($posts) {
  2998.             //preload posts
  2999.             $posts = ED::formatPost($posts);
  3000.         }
  3001.  
  3002.         return $posts;
  3003.  
  3004.     }
  3005.  
  3006.     /**
  3007.      * Retrieves the html block for board statistics.
  3008.      *
  3009.      * @since   3.0
  3010.      * @access  public
  3011.      */
  3012.     public static function getBoardStatistics()
  3013.     {
  3014.         $config = ED::config();
  3015.         $allowed = true;
  3016.         $disallowedGroups = $config->get('main_exclude_frontend_statistics');
  3017.  
  3018.         if (!$config->get('main_frontend_statistics')) {
  3019.             return;
  3020.         }
  3021.  
  3022.         if (!empty($disallowedGroups)) {
  3023.  
  3024.             //Remove whitespace
  3025.             $disallowedGroups = trim($disallowedGroups);
  3026.             $disallowedGroups = explode(',', $disallowedGroups);
  3027.  
  3028.             $my = JFactory::getUser();
  3029.             $groups = $my->groups;
  3030.  
  3031.             $result = array_intersect($groups, $disallowedGroups);
  3032.  
  3033.             $allowed = !$result ? true : false;
  3034.         }
  3035.  
  3036.         if (!$allowed) {
  3037.             return;
  3038.         }
  3039.  
  3040.         $theme = ED::themes();
  3041.  
  3042.         $postModel = ED::model('Posts');
  3043.         $totalPosts = $postModel->getTotal();
  3044.  
  3045.         $resolvedPosts = $postModel->getTotalResolved();
  3046.         $unresolvedPosts = $postModel->getUnresolvedCount();
  3047.  
  3048.         $userModel = ED::model('Users');
  3049.         $totalUsers = $userModel->getTotalUsers();
  3050.  
  3051.  
  3052.         $ids = $userModel->getLatestUser();
  3053.         $latestMember = ED::user($ids);
  3054.  
  3055.         // Total guests
  3056.         $totalGuests = $userModel->getTotalGuests();
  3057.  
  3058.         // Online users
  3059.         $onlineUsers = $userModel->getOnlineUsers();
  3060.  
  3061.         $theme->set('latestMember', $latestMember);
  3062.         $theme->set('unresolvedPosts', $unresolvedPosts);
  3063.         $theme->set('resolvedPosts', $resolvedPosts);
  3064.         $theme->set('totalUsers', $totalUsers);
  3065.         $theme->set('totalPosts', $totalPosts);
  3066.         $theme->set('onlineUsers', $onlineUsers);
  3067.         $theme->set('totalGuests', $totalGuests);
  3068.  
  3069.         return $theme->output('site/frontpage/stats');
  3070.     }
  3071.  
  3072.     /**
  3073.      * Method to retrieve a EasyBlogUser object
  3074.      *
  3075.      * @since   1.0
  3076.      * @access  public
  3077.      * @param   null
  3078.      * @return  SocialUser      The user's object
  3079.      */
  3080.     public static function user( $ids = null , $debug = false )
  3081.     {
  3082.         $path = JPATH_ADMINISTRATOR . '/components/com_easydiscuss/includes/user/user.php';
  3083.         include_once($path);
  3084.  
  3085.         return EasyDiscussUser::factory($ids, $debug);
  3086.     }
  3087.  
  3088.     /**
  3089.      * Retrieve the html block for who's viewing this page.
  3090.      *
  3091.      * @access  public
  3092.      * @param   string  $url
  3093.      */
  3094.     public static function getWhosOnline($uri = '')
  3095.     {
  3096.         $config = ED::config();
  3097.         $enabled = $config->get('main_viewingpage');
  3098.  
  3099.         if (!$enabled) {
  3100.             return;
  3101.         }
  3102.  
  3103.         // Default hash
  3104.         $hash = md5(JRequest::getURI());
  3105.  
  3106.         if (!empty($uri)) {
  3107.             $hash = md5($uri);
  3108.         }
  3109.  
  3110.         $model = ED::model('Users');
  3111.         $users = $model->getPageViewers($hash);
  3112.  
  3113.         if (!$users) {
  3114.             return;
  3115.         }
  3116.  
  3117.         $theme = ED::themes();
  3118.         $theme->set('users', $users);
  3119.  
  3120.         return $theme->output('site/post/default.viewers');
  3121.     }
  3122.  
  3123.     public static function getListLimit()
  3124.     {
  3125.         $app        = JFactory::getApplication();
  3126.         $default    = ED::jconfig()->get( 'list_limit' );
  3127.  
  3128.         if( $app->isAdmin() )
  3129.         {
  3130.             return $default;
  3131.         }
  3132.  
  3133.         $app    = JFactory::getApplication();
  3134.         $menus  = $app->getMenu();
  3135.         $menu   = $menus->getActive();
  3136.         $limit  = -2;
  3137.  
  3138.         if( is_object( $menu ) )
  3139.         {
  3140.             $params = DiscussHelper::getRegistry( $menu->params );
  3141.             $limit  = $params->get( 'limit' , '-2' );
  3142.         }
  3143.  
  3144.         if( $limit == '-2' )
  3145.         {
  3146.             // Use default configurations.
  3147.             $config = DiscussHelper::getConfig();
  3148.             $limit  = $config->get( 'layout_list_limit', '-2' );
  3149.         }
  3150.  
  3151.         // Revert to joomla's pagination if configured to inherit from Joomla
  3152.         if( $limit == '0' || $limit == '-1' || $limit == '-2' )
  3153.         {
  3154.             $limit      = $default;
  3155.         }
  3156.  
  3157.         return $limit;
  3158.     }
  3159.  
  3160.     public static function getRegistrationLink()
  3161.     {
  3162.         $config = DiscussHelper::getConfig();
  3163.  
  3164.         $default    = JRoute::_( 'index.php?option=com_user&view=register' );
  3165.         if( DiscussHelper::getJoomlaVersion() >= '1.6' )
  3166.         {
  3167.             $default    = JRoute::_( 'index.php?option=com_users&view=registration' );
  3168.         }
  3169.  
  3170.         switch( $config->get( 'main_login_provider' ) )
  3171.         {
  3172.             case 'joomla':
  3173.                 $link   = $default;
  3174.                 break;
  3175.  
  3176.             case 'cb':
  3177.                 $link   = JRoute::_( 'index.php?option=com_comprofiler&task=registers' );
  3178.                 break;
  3179.  
  3180.             case 'easysocial':
  3181.  
  3182.                 if (ED::easysocial()->exists()) {
  3183.                     $link = FRoute::registration();
  3184.                 } else {
  3185.                     $link = $default;
  3186.                 }
  3187.  
  3188.                 break;
  3189.  
  3190.             case 'jomsocial':
  3191.                 $link   = JRoute::_( 'index.php?option=com_community&view=register' );
  3192.                 $file   = JPATH_ROOT . '/components/com_community/libraries/core.php';
  3193.  
  3194.                 if (JFile::exists($file)) {
  3195.                     require_once( $file );
  3196.                     $link   = CRoute::_( 'index.php?option=com_community&view=register' );
  3197.                 }
  3198.             break;
  3199.         }
  3200.  
  3201.         return $link;
  3202.     }
  3203.  
  3204.     public static function getEditProfileLink()
  3205.     {
  3206.         $config = ED::config();
  3207.  
  3208.         $link = EDR::_('view=profile&layout=edit');
  3209.  
  3210.         if ($config->get('integration_easysocial_toolbar_profile')) {
  3211.             $easysocial = ED::easysocial();
  3212.  
  3213.             if ($easysocial->exists()) {
  3214.                 $link = FRoute::profile(array('layout' => 'edit'));
  3215.             }
  3216.         }
  3217.  
  3218.         return $link;
  3219.     }
  3220.  
  3221.     public static function getResetPasswordLink()
  3222.     {
  3223.         $config     = DiscussHelper::getConfig();
  3224.  
  3225.         $default    = JRoute::_( 'index.php?option=com_user&view=reset' );
  3226.  
  3227.         if( DiscussHelper::getJoomlaVersion() >= '1.6' )
  3228.         {
  3229.             $default    = JRoute::_( 'index.php?option=com_users&view=reset' );
  3230.         }
  3231.  
  3232.  
  3233.         switch( $config->get( 'main_login_provider' ) )
  3234.         {
  3235.             case 'easysocial':
  3236.  
  3237.                 if (ED::easysocial()->exists()) {
  3238.                     $link = FRoute::profile( array( 'layout' => 'forgetPassword' ) );
  3239.                 } else {
  3240.                     $link = $default;
  3241.                 }
  3242.                 break;
  3243.             case 'joomla':
  3244.             case 'cb':
  3245.             case 'jomsocial':
  3246.             default:
  3247.                 $link   = $default;
  3248.                 break;
  3249.         }
  3250.  
  3251.         return $link;
  3252.     }
  3253.  
  3254.     public static function getDefaultRepliesSorting()
  3255.     {
  3256.         $config = ED::config();
  3257.         $defaultFilter = $config->get('layout_replies_sorting');
  3258.  
  3259.         if ($defaultFilter == 'voted' && !$config->get('main_allowvote')) {
  3260.             $defaultFilter = 'oldest';
  3261.         }
  3262.  
  3263.         if ($defaultFilter == 'likes' && !$config->get('main_likes_replies')) {
  3264.             $defaultFilter = 'oldest';
  3265.         }
  3266.  
  3267.         return $defaultFilter;
  3268.     }
  3269.  
  3270.     /**
  3271.      * Allows caller to set the page title.
  3272.      *
  3273.      * @since   4.0
  3274.      * @access  public
  3275.      * @param   string
  3276.      * @return
  3277.      */
  3278.     public static function setPageTitle($text = '', $pagination = null)
  3279.     {
  3280.         $text = JText::_($text);
  3281.  
  3282.         // now check if site name is needed or not.
  3283.         $app = JFactory::getApplication();
  3284.         $doc = JFactory::getDocument();
  3285.  
  3286.         $app = JFactory::getApplication();
  3287.         $itemid = $app->input->get('Itemid', '');
  3288.  
  3289.         $menu = JFactory::getApplication()->getMenu();
  3290.         $item = $menu->getItem($itemid);
  3291.  
  3292.         if (is_object($item)) {
  3293.            
  3294.             $params = $item->params;
  3295.  
  3296.             if (!$params instanceof JRegistry) {
  3297.                 $params = new JRegistry($item->params);
  3298.             }
  3299.  
  3300.             $customPageTitle = $params->get('page_title', '');
  3301.  
  3302.             if ($customPageTitle) {
  3303.                 $text = $customPageTitle;
  3304.             }
  3305.         }
  3306.  
  3307.  
  3308.         // Prepare Joomla's site title if necessary.
  3309.         $jConfig = ED::jConfig();
  3310.         $addTitle = $jConfig->get('sitename_pagetitles');
  3311.  
  3312.         // Only add Joomla's site title if it was configured to.
  3313.         if ($addTitle) {
  3314.  
  3315.             $siteTitle = $jConfig->get('sitename');
  3316.  
  3317.             if ($addTitle == 1) {
  3318.                 $text = $siteTitle . ' - ' . $text;
  3319.             }
  3320.  
  3321.             if ($addTitle == 2) {
  3322.                 $text = $text . ' - ' . $siteTitle;
  3323.             }
  3324.         }
  3325.  
  3326.         if ($pagination) {
  3327.             $paginationNumber = $pagination->getPageNumber();
  3328.  
  3329.             if ($paginationNumber > 1) {
  3330.                 $paginationText = JText::sprintf('COM_EASYDISCUSS_PAGINATION_TEXT', $paginationNumber);
  3331.                 $text = $text . ' - ' . $paginationText;
  3332.             }
  3333.         }
  3334.  
  3335.         $doc->setTitle($text);
  3336.     }
  3337.  
  3338.  
  3339.     public static function setMeta()
  3340.     {
  3341.         $config = DiscussHelper::getConfig();
  3342.         $db     = DiscussHelper::getDBO();
  3343.  
  3344.  
  3345.         $menu   = JFactory::getApplication()->getMenu();
  3346.         $item   = $menu->getActive();
  3347.  
  3348.         $result = new stdClass();
  3349.         $result->description    = $config->get( 'main_description' );
  3350.         $result->keywords       = '';
  3351.  
  3352.         $description    = '';
  3353.  
  3354.         if( is_object( $item ) )
  3355.         {
  3356.             $params         = $item->params;
  3357.  
  3358.             if(! $params instanceof JRegistry )
  3359.             {
  3360.                 $params         = DiscussHelper::getRegistry( $item->params );
  3361.             }
  3362.  
  3363.             $description    = $params->get( 'menu-meta_description' , '' );
  3364.             $keywords       = $params->get( 'menu-meta_keywords' , '' );
  3365.  
  3366.             if( ! empty ( $description ) )
  3367.             {
  3368.                 $result->description    = $description;
  3369.             }
  3370.  
  3371.             if( ! empty ( $keywords ) )
  3372.             {
  3373.                 $result->keywords   = $keywords;
  3374.             }
  3375.         }
  3376.  
  3377.         $document = JFactory::getDocument();
  3378.         if ( empty( $result->keywords ) && empty( $result->description ) )
  3379.         {
  3380.             // Get joomla default description.
  3381.             $jConfig    = ED::jconfig();
  3382.             $joomlaDesc = $jConfig->get('MetaDesc');
  3383.  
  3384.             $metaDesc   = $description . ' - ' . $joomlaDesc;
  3385.             $document->setMetadata('description', $metaDesc);
  3386.         }
  3387.         else
  3388.         {
  3389.             if ( !empty( $result->keywords ) )
  3390.             {
  3391.                 $document->setMetadata('keywords', $result->keywords);
  3392.             }
  3393.  
  3394.             if ( !empty( $result->description ) )
  3395.             {
  3396.                 $document->setMetadata('description', $result->description);
  3397.             }
  3398.         }
  3399.     } //end function setMeta
  3400.  
  3401.     public static function getFrontpageCategories()
  3402.     {
  3403.         $catModel       = ED::model( 'Categories' );
  3404.         $newPostCount   = 0;
  3405.  
  3406.         if( !$categories = $catModel->getCategories() )
  3407.         {
  3408.             return array();
  3409.         }
  3410.  
  3411.         foreach ($categories as $category)
  3412.         {
  3413.             $postModel = ED::model( 'Posts' );
  3414.             $category->newCount = $postModel->getNewCount( '' , $category->id , null , false );
  3415.             $newPostCount += $category->newCount;
  3416.         }
  3417.  
  3418.         // Temporary store in user state.
  3419.         $app = JFactory::getApplication();
  3420.         $app->setUserState( 'com_easydiscuss.helper.totalnewpost', $newPostCount );
  3421.  
  3422.         return $categories;
  3423.     }
  3424.  
  3425.     public static function log( $var = '', $force = 0 )
  3426.     {
  3427.         $debugroot = DISCUSS_HELPERS . '/debug';
  3428.  
  3429.         $firephp = false;
  3430.         $chromephp = false;
  3431.  
  3432.         if( JFile::exists( $debugroot . '/fb.php' ) && JFile::exists( $debugroot . '/FirePHP.class.php' ) )
  3433.         {
  3434.             include_once( $debugroot . '/fb.php' );
  3435.             fb( $var );
  3436.         }
  3437.  
  3438.         if( JFile::exists( $debugroot . '/chromephp.php' ) )
  3439.         {
  3440.             include_once( $debugroot . '/chromephp.php' );
  3441.             ChromePhp::log( $var );
  3442.         }
  3443.     }
  3444.  
  3445.     /**
  3446.      * Determines if the user is a moderator of the forum
  3447.      *
  3448.      * @since   4.0
  3449.      * @access  public
  3450.      * @param   string
  3451.      * @return
  3452.      */
  3453.     public static function isModerator($categoryId = null, $userId = null)
  3454.     {
  3455.         $moderator = ED::moderator()->isModerator($categoryId, $userId);
  3456.  
  3457.         return $moderator;
  3458.     }
  3459.  
  3460.     public static function getUserGroupId(JUser $user, $recursive = true)
  3461.     {
  3462.         $groups = JAccess::getGroupsByUser($user->id, $recursive);
  3463.  
  3464.         return $groups;
  3465.     }
  3466.  
  3467.     /**
  3468.      * Method determines if the content needs to be parsed through any parser or not.
  3469.      *
  3470.      * @since   3.0
  3471.      * @access  public
  3472.      * @param   string  The content's string.
  3473.      */
  3474.     public static function parseContent( $content, $forceBBCode=false )
  3475.     {
  3476.         $config = ED::config();
  3477.  
  3478.         $content = ED::string()->escape($content);
  3479.  
  3480.         // Pass it to bbcode parser.
  3481.         $content = ED::parser()->bbcode( $content );
  3482.         $content = nl2br($content);
  3483.  
  3484.         //Remove BR in pre tag
  3485.         $content = preg_replace_callback('/<pre.*?\>(.*?)<\/pre>/ims', array( 'EasyDiscussParser' , 'removeBr' ) , $content );
  3486.         $content = preg_replace_callback('/<ol.*?\>(.*?)<\/ol>/ims', array( 'EasyDiscussParser' , 'removeBr' ) , $content );
  3487.         $content = preg_replace_callback('/<ul.*?\>(.*?)<\/ul>/ims', array( 'EasyDiscussParser' , 'removeBr' ) , $content );
  3488.  
  3489.         $content = str_ireplace("</pre><br />", '</pre>', $content);
  3490.         $content = str_ireplace("</ol><br />", '</ol>', $content);
  3491.         $content = str_ireplace("</ol>\r\n<br />", '</ol>', $content);
  3492.         $content = str_ireplace("</ul><br />", '</ul>', $content);
  3493.         $content = str_ireplace("</ul>\r\n<br />", '</ul>', $content);
  3494.         $content = str_ireplace("</pre>\r\n<br />", '</pre>', $content);
  3495.         $content = str_ireplace("</blockquote><br />", '</blockquote>', $content);
  3496.         $content = str_ireplace("</blockquote>\r\n<br />", '</blockquote>', $content);
  3497.  
  3498.         return $content;
  3499.     }
  3500.  
  3501.     /**
  3502.      * Triggers plugins.
  3503.      *
  3504.      * @since   3.0
  3505.      * @access  public
  3506.      */
  3507.     public static function triggerPlugins( $type , $eventName , &$data ,$hasReturnValue = false )
  3508.     {
  3509.         $path = JPATH_ADMINISTRATOR . '/components/com_easydiscuss/includes/events/events.php';
  3510.         include_once($path);
  3511.  
  3512.         EasyDiscussEvents::importPlugin($type);
  3513.  
  3514.         $args = array( 'post' , &$data );
  3515.  
  3516.         $returnValue = call_user_func_array( 'EasyDiscussEvents::' . $eventName , $args );
  3517.  
  3518.         if ($hasReturnValue) {
  3519.             return trim( implode( "\n" , $returnValue ) );
  3520.         }
  3521.  
  3522.         return;
  3523.     }
  3524.  
  3525.     /**
  3526.      * Renders a module in the component
  3527.      *
  3528.      * @since   4.0
  3529.      * @access  public
  3530.      * @param   string
  3531.      * @return
  3532.      */
  3533.     public static function renderModule($position, $attributes = array(), $content = null)
  3534.     {
  3535.         jimport('joomla.application.module.helper');
  3536.  
  3537.         $doc = JFactory::getDocument();
  3538.         $renderer = $doc->loadRenderer('module');
  3539.         $buffer = '';
  3540.         $modules = JModuleHelper::getModules($position);
  3541.  
  3542.         foreach ($modules as $module) {
  3543.  
  3544.             // Get the module output
  3545.             $output = $renderer->render($module, $attributes, $content);
  3546.  
  3547.             $theme = ED::themes();
  3548.             $theme->set('position', $position);
  3549.             $theme->set('output', $output);
  3550.  
  3551.             $buffer .= $theme->output('site/widgets/module');
  3552.         }
  3553.  
  3554.         return $buffer;
  3555.     }
  3556.  
  3557.     public static function getEditorType( $type = '' )
  3558.     {
  3559.         // Cater for #__discuss_posts column content_type
  3560.         $config = ED::getConfig();
  3561.  
  3562.         if ($config->get('layout_editor') == 'bbcode') {
  3563.             return 'bbcode';
  3564.         } else {
  3565.             return 'html';
  3566.         }
  3567.     }
  3568.  
  3569.     /**
  3570.      * Formats the content of a post
  3571.      *
  3572.      * @since   1.0
  3573.      * @access  public
  3574.      * @param   string
  3575.      * @return
  3576.      */
  3577.     public static function formatContent($post)
  3578.     {
  3579.         $config = ED::config();
  3580.  
  3581.         // @ 4.0 we need to check if this post has the 'preview' or not. if yes, we just use it. if not, lets format it.
  3582.         if ($post->preview) {
  3583.  
  3584.             // Apply word censorship on the content
  3585.             $content = ED::badwords()->filter($post->preview);
  3586.  
  3587.             return $content;
  3588.         }
  3589.  
  3590.         // Determine the current editor
  3591.         $editor = $config->get('layout_editor', 'bbcode');
  3592.  
  3593.         // If the post is bbcode source and the current editor is bbcode
  3594.         if (($post->content_type == 'bbcode' || is_null($post->content_type)) && $editor == 'bbcode') {
  3595.  
  3596.             $content = $post->content;
  3597.  
  3598.             // Allow syntax highlighter even on html codes.
  3599.             $content = ED::parser()->replaceCodes($content);
  3600.  
  3601.             $content = ED::parser()->bbcode($content , true);
  3602.  
  3603.             // Since this is a bbcode content and source, we want to replace \n with <br /> tags.
  3604.             $content = nl2br($content);
  3605.         }
  3606.  
  3607.         // If the admin decides to switch from bbcode to wysiwyg editor, we need to format it back
  3608.         if( $post->content_type == 'bbcode' && $editor != 'bbcode' )
  3609.         {
  3610.             $content    = $post->content;
  3611.  
  3612.             //strip this kind of tag -> &nbsp; &amp;
  3613.             $content = strip_tags(html_entity_decode($content));
  3614.  
  3615.             // Since the original content is bbcode, we don't really need to do any replacements.
  3616.             // Just feed it in through bbcode formatter.
  3617.             $content    = ED::parser()->bbcode( $content );
  3618.         }
  3619.  
  3620.         // If the admin decides to switch from wysiwyg to bbcode, we need to fix the content here.
  3621.         if( $post->content_type != 'bbcode' && !is_null($post->content_type) && $editor == 'bbcode' )
  3622.         {
  3623.             $content    = $post->content;
  3624.  
  3625.             // Switch html back to bbcode
  3626.             $content    = ED::parser()->html2bbcode( $content );
  3627.  
  3628.             // Update the quote messages
  3629.             $content    = ED::parser()->quoteBbcode( $content );
  3630.         }
  3631.  
  3632.         // If the content is from wysiwyg and editor is also wysiwyg, we only do specific formatting.
  3633.         if( $post->content_type != 'bbcode' && $editor != 'bbcode' )
  3634.         {
  3635.             $content    = $post->content;
  3636.  
  3637.             // Allow syntax highlighter even on html codes.
  3638.             $content    = ED::parser()->replaceCodes( $content );
  3639.         }
  3640.  
  3641.         // Apply word censorship on the content
  3642.         $content    = ED::badwords()->filter($content);
  3643.  
  3644.         return $content;
  3645.     }
  3646.  
  3647.     /**
  3648.      * cache for post related items.
  3649.      *
  3650.      * @since   4.0
  3651.      * @access  public
  3652.      * @param   string
  3653.      * @return
  3654.      */
  3655.     public static function cache()
  3656.     {
  3657.         static $cache = null;
  3658.  
  3659.         if (!$cache) {
  3660.             require_once(__DIR__ . '/cache/cache.php');
  3661.  
  3662.             $cache = new EasyDiscussCache();
  3663.         }
  3664.  
  3665.         return $cache;
  3666.     }
  3667.  
  3668.     /**
  3669.      * cache for post related items.
  3670.      *
  3671.      * @since   4.0
  3672.      * @access  public
  3673.      * @param   string
  3674.      * @return
  3675.      */
  3676.     public static function rest()
  3677.     {
  3678.         static $rest = null;
  3679.  
  3680.         if (!$rest) {
  3681.             require_once(__DIR__ . '/rest/rest.php');
  3682.  
  3683.             $rest = new EasyDiscussRest();
  3684.         }
  3685.  
  3686.         return $rest;
  3687.     }
  3688.  
  3689.  
  3690.     /**
  3691.      * include akisment class file
  3692.      *
  3693.      * @since   4.0
  3694.      * @access  public
  3695.      * @param   string
  3696.      * @return
  3697.      */
  3698.     public static function akismet()
  3699.     {
  3700.         if (! class_exists('Akismet')) {
  3701.             require_once(__DIR__ . '/akismet/akismet.php');
  3702.         }
  3703.     }
  3704.  
  3705.     /**
  3706.      * Ensures that the token is valid
  3707.      *
  3708.      * @since   4.0
  3709.      * @access  public
  3710.      * @param   string
  3711.      * @return
  3712.      */
  3713.     public static function checkToken($method = 'post')
  3714.     {
  3715.         JRequest::checkToken($method) or die('Invalid Token');
  3716.     }
  3717.  
  3718.     // For displaying on frontend
  3719.     public static function bbcodeHtmlSwitcher( $post = '', $type = '', $isEditing = false )
  3720.     {
  3721.         $config = ED::config();
  3722.  
  3723.         if( $type == 'signature' || $type == 'description' ) {
  3724.             $temp = $post;
  3725.             $post = new stdClass();
  3726.             $post->content = $temp;
  3727.             $post->content_type = 'bbcode';
  3728.             $editor = 'bbcode';
  3729.         } else {
  3730.             $editor = $config->get( 'layout_editor' );
  3731.         }
  3732.  
  3733.         if ($editor != 'bbcode') {
  3734.             $editor = 'html';
  3735.         }
  3736.  
  3737.         if ($post->content_type == 'bbcode') {
  3738.             if ($editor == 'bbcode') {
  3739.  
  3740.                 $content = $post->content;
  3741.  
  3742.                 //If content_type is bbcode and editor is bbcode
  3743.                 if (! $isEditing) {
  3744.                     $content = ED::parser()->bbcode($content);
  3745.                     $content = ED::parser()->removeBrTag($content);
  3746.                 }
  3747.             } else {
  3748.                 //If content_type is bbcode and editor is html
  3749.                 // Need content raw to work
  3750.                 $content = $post->post->content;
  3751.                 $content = ED::parser()->bbcode($content);
  3752.                 $content = ED::parser()->removeBrTag($content);
  3753.             }
  3754.         } else {
  3755.             // content_type is html
  3756.  
  3757.             if ($editor == 'bbcode') {
  3758.  
  3759.                 $content = $post->content;
  3760.  
  3761.                 //If content_type is html and editor is bbcode
  3762.                 if ($isEditing) {
  3763.                     $content = ED::parser()->quoteBbcode($content);
  3764.                     $content = ED::parser()->smiley2bbcode($content); // we need to parse smiley 1st before we parse htmltobbcode.
  3765.                     $content = ED::parser()->html2bbcode($content);
  3766.                 } else {
  3767.  
  3768.                     //Quote all bbcode here
  3769.                     $content = ED::parser()->quoteBbcode($content);
  3770.                 }
  3771.             } else {
  3772.                 //If content_type is html and editor is html
  3773.                 $content = $post->content;
  3774.             }
  3775.         }
  3776.  
  3777.         // Apply censorship
  3778.         $content = ED::badwords()->filter($content);
  3779.  
  3780.         return $content;
  3781.     }
  3782.  
  3783.     public static function getLoginLink($returnURL = '')
  3784.     {
  3785.         if (!empty($returnURL)) {
  3786.             $returnURL = '&return=' . $returnURL;
  3787.         }
  3788.  
  3789.         $link = DiscussRouter::_('index.php?option=com_users&view=login' . $returnURL);
  3790.  
  3791.         return $link;
  3792.     }
  3793.  
  3794.     public static function getPostStatusAndTypes( $posts = null)
  3795.     {
  3796.         if (empty($posts)) {
  3797.             return;
  3798.         }
  3799.  
  3800.         foreach ($posts as $post) {
  3801.             $user = ED::user($post->getOwner()->id);
  3802.  
  3803.             $post->badges = $user->getBadges();
  3804.  
  3805.             // Translate post status from integer to string
  3806.             switch($post->post_status) {
  3807.                 case '0':
  3808.                     $post->post_status_class = '';
  3809.                     $post->post_status = '';
  3810.                     break;
  3811.                 case '1':
  3812.                     $post->post_status_class = '-on-hold';
  3813.                     $post->post_status = JText::_( 'COM_EASYDISCUSS_POST_STATUS_ON_HOLD' );
  3814.                     break;
  3815.                 case '2':
  3816.                     $post->post_status_class = '-accept';
  3817.                     $post->post_status = JText::_( 'COM_EASYDISCUSS_POST_STATUS_ACCEPTED' );
  3818.                     break;
  3819.                 case '3':
  3820.                     $post->post_status_class = '-working-on';
  3821.                     $post->post_status = JText::_( 'COM_EASYDISCUSS_POST_STATUS_WORKING_ON' );
  3822.                     break;
  3823.                 case '4':
  3824.                     $post->post_status_class = '-reject';
  3825.                     $post->post_status = JText::_( 'COM_EASYDISCUSS_POST_STATUS_REJECT' );
  3826.                     break;
  3827.                 default:
  3828.                     $post->post_status_class = '';
  3829.                     $post->post_status = '';
  3830.                     break;
  3831.             }
  3832.  
  3833.             $alias = $post->post_type;
  3834.             $modelPostTypes = ED::model('Posttypes');
  3835.  
  3836.             // Get each post's post status title
  3837.             $title = $modelPostTypes->getTitle($alias);
  3838.             $post->post_type = $title;
  3839.  
  3840.             // Get each post's post status suffix
  3841.             $suffix = $modelPostTypes->getSuffix($alias);
  3842.             $post->suffix = $suffix;
  3843.         }
  3844.  
  3845.         return $posts;
  3846.     }
  3847.  
  3848.     /**
  3849.      * Determines if the user falls under the moderation threshold
  3850.      *
  3851.      * @since   4.0
  3852.      * @access  public
  3853.      * @param   string
  3854.      * @return
  3855.      */
  3856.     public static function isModerateThreshold($userId = null)
  3857.     {
  3858.         $user = ED::user($userId);
  3859.  
  3860.         return $user->moderateUsersPost();
  3861.     }
  3862.  
  3863.     /**
  3864.      * Backwards compatibility purpose
  3865.      *
  3866.      * @since   4.0
  3867.      * @access  public
  3868.      * @param   string
  3869.      * @return
  3870.      */
  3871.     public static function __callStatic($method, $args)
  3872.     {
  3873.         // If the called method exists in the legacy, we should just use it
  3874.         if (method_exists('EDLegacy', $method)) {
  3875.             return call_user_func_array(array('EDLegacy', $method), $args);
  3876.         }
  3877.  
  3878.         // Here, we are under the assumption, the library exists
  3879.         $file = dirname(__FILE__) . '/' . strtolower($method) . '/' . strtolower($method) . '.php';
  3880.  
  3881.         require_once($file);
  3882.  
  3883.         $class = 'EasyDiscuss' . ucfirst($method);
  3884.  
  3885.         if (count($args) == 1) {
  3886.             $args = $args[0];
  3887.         }
  3888.  
  3889.         if (!$args) {
  3890.             $args = null;
  3891.         }
  3892.  
  3893.         $obj = new $class($args);
  3894.  
  3895.         return $obj;
  3896.     }
  3897.  
  3898.     /**
  3899.      * Gets the current timezone of the site
  3900.      *
  3901.      * @since   4.0
  3902.      * @access  public
  3903.      * @param   string
  3904.      * @return
  3905.      */
  3906.     public static function getTimeZone()
  3907.     {
  3908.         // Get server's timezone
  3909.         $user = JFactory::getUser();
  3910.         $jconfig = ED::jconfig();
  3911.         $timezone = $jconfig->get('offset');
  3912.  
  3913.         // If user is a member, get their timezone
  3914.         if ($user->id) {
  3915.             $timezone = $user->getParam('timezone', $timezone);
  3916.         }
  3917.  
  3918.         return $timezone;
  3919.     }
  3920.  
  3921.     /**
  3922.      * Gets the current timezone of the site
  3923.      *
  3924.      * @since   4.0
  3925.      * @access  public
  3926.      * @param   string
  3927.      * @return
  3928.      */
  3929.     public static function getTimeZoneOffset()
  3930.     {
  3931.         $date = ED::date();
  3932.  
  3933.         $timezone = ED::getTimeZone();
  3934.         $timezone = new DateTimeZone($timezone);
  3935.  
  3936.         $date->setTimezone($timezone);
  3937.  
  3938.         $offset = $date->getOffsetFromGmt(true);
  3939.  
  3940.         return $offset;
  3941.     }
  3942.  
  3943.  
  3944.     /**
  3945.      * Renders the DiscussProfile table
  3946.      *
  3947.      * @since   4.0
  3948.      * @access  public
  3949.      * @param   string
  3950.      * @return
  3951.      */
  3952.     public static function profile($id = null)
  3953.     {
  3954.         $user = ED::user($id);
  3955.         return $user;
  3956.     }
  3957.  
  3958.     public static function validateUserType($usertype)
  3959.     {
  3960.         $config = ED::config();
  3961.         $acl = ED::acl();
  3962.  
  3963.         switch($usertype)
  3964.         {
  3965.             case 'guest':
  3966.                 $enable = $acl->allowed('add_reply', 0);
  3967.                 break;
  3968.             case 'twitter':
  3969.                 $enable = $config->get('integration_twitter_enable');
  3970.                 break;
  3971.             case 'facebook':
  3972.                 $enable = $config->get('integration_facebook_enable1');
  3973.                 break;
  3974.             case 'linkedin':
  3975.                 $enable = $config->get('integration_linkedin_enable1');
  3976.                 break;
  3977.             default:
  3978.                 $enable = false;
  3979.         }
  3980.  
  3981.         return $enable;
  3982.     }
  3983.  
  3984.     /**
  3985.      * Retrieves the default avatar
  3986.      *
  3987.      * @since   4.0
  3988.      * @access  public
  3989.      * @param   string
  3990.      * @return
  3991.      */
  3992.     public static function getDefaultAvatar()
  3993.     {
  3994.         $uri = rtrim(JURI::root(), '/');
  3995.         $file = '/media/com_easydiscuss/images/default_avatar.png';
  3996.  
  3997.         // @TODO: Allow overrides
  3998.  
  3999.         $uri = $uri . $file;
  4000.  
  4001.         return $uri;
  4002.     }
  4003.  
  4004.     public static function getThemeObject($name)
  4005.     {
  4006.         jimport('joomla.filesystem.file');
  4007.         jimport('joomla.filesystem.folder');
  4008.  
  4009.         $file = DISCUSS_THEMES . '/' . $name . '/config.xml';
  4010.         $exists = JFile::exists($file);
  4011.  
  4012.         if (!$exists) {
  4013.             return false;
  4014.         }
  4015.  
  4016.         $parser = JFactory::getXML($file);
  4017.  
  4018.         $obj = new stdClass();
  4019.         $obj->element = $name;
  4020.         $obj->name = $name;
  4021.         $obj->path = $file;
  4022.         $obj->writable = is_writable($file);
  4023.         $obj->created = JText::_('Unknown');
  4024.         $obj->updated = JText::_('Unknown');
  4025.         $obj->author = JText::_('Unknown');
  4026.         $obj->version = JText::_('Unknown');
  4027.         $obj->desc = JText::_('Unknown');
  4028.  
  4029.         if (ED::isJoomla30()) {
  4030.  
  4031.             $childrens = $parser->children();
  4032.  
  4033.             foreach ($childrens as $key => $value) {
  4034.                 if ($key == 'description') {
  4035.                     $key = 'desc';
  4036.                 }
  4037.  
  4038.                 $obj->$key = (string) $value;
  4039.             }
  4040.  
  4041.             $obj->path = $file;
  4042.         } else {
  4043.  
  4044.             $contents = JFile::read($file);
  4045.  
  4046.             $parser = JFactory::getXMLParser('Simple');
  4047.             $parser->loadString($contents);
  4048.  
  4049.             $created = $parser->document->getElementByPath('created');
  4050.             if ($created) {
  4051.                 $obj->created = $created->data();
  4052.             }
  4053.  
  4054.             $updated = $parser->document->getElementByPath('updated');
  4055.             if ($updated) {
  4056.                 $obj->updated = $updated->data();
  4057.             }
  4058.  
  4059.             $author = $parser->document->getElementByPath('author');
  4060.             if ($author) {
  4061.                 $obj->author = $author->data();
  4062.             }
  4063.  
  4064.             $version = $parser->document->getElementByPath('version');
  4065.             if ($version) {
  4066.                 $obj->version = $version->data();
  4067.             }
  4068.  
  4069.             $description = $parser->document->getElementByPath('description');
  4070.             if ($description)
  4071.             {
  4072.                 $obj->desc = $description->data();
  4073.             }
  4074.  
  4075.             $obj->path = $file;
  4076.         }
  4077.  
  4078.         return $obj;
  4079.     }
  4080.  
  4081.     /**
  4082.      * Parses a csv file to array of data
  4083.      *
  4084.      * @since   4.0
  4085.      * @param   string  Filename to parse
  4086.      * @return  Array   Arrays of the data
  4087.      */
  4088.     public static function parseCSV($file, $firstRowName = true, $firstColumnKey = true)
  4089.     {
  4090.         if (!JFile::exists($file)) {
  4091.             return array();
  4092.         }
  4093.  
  4094.         $handle = fopen($file, 'r');
  4095.  
  4096.         $line = 0;
  4097.  
  4098.         $columns = array();
  4099.  
  4100.         $data = array();
  4101.  
  4102.         while (($row = fgetcsv($handle)) !== false) {
  4103.  
  4104.             if ($firstRowName && $line === 0) {
  4105.                 $columns = $row;
  4106.             } else {
  4107.                 $tmp = array();
  4108.  
  4109.                 if ($firstRowName) {
  4110.                     foreach ($row as $i => $v) {
  4111.                         $tmp[$columns[$i]] = $v;
  4112.                     }
  4113.                 } else {
  4114.                     $tmp = $row;
  4115.                 }
  4116.  
  4117.                 if ($firstColumnKey) {
  4118.                     if ($firstRowName) {
  4119.                         $data[$tmp[$columns[0]]] = $tmp;
  4120.                     } else {
  4121.                         $data[$tmp[0]] = $tmp;
  4122.                     }
  4123.                 } else {
  4124.                     $data[] = $tmp;
  4125.                 }
  4126.             }
  4127.  
  4128.             $line++;
  4129.         }
  4130.  
  4131.         fclose($handle);
  4132.  
  4133.         return $data;
  4134.     }
  4135.  
  4136.     /**
  4137.      * Includes a file given a particular namespace in POSIX format.
  4138.      *
  4139.      * @since   4.0
  4140.      * @access  public
  4141.      * @param   string  $file       Eg: admin:/tables/table will include /administrator/components/com_easydiscuss/tables/table.php
  4142.      * @return  boolean             True on success false otherwise
  4143.      */
  4144.     public static function import( $namespace )
  4145.     {
  4146.         static $locations   = array();
  4147.  
  4148.         if( !isset( $locations[ $namespace ] ) )
  4149.         {
  4150.             // Explode the parts to know exactly what to lookup for
  4151.             $parts      = explode( ':' , $namespace );
  4152.  
  4153.             // Non POSIX standard.
  4154.             if( count( $parts ) <= 1 )
  4155.             {
  4156.                 return false;
  4157.             }
  4158.  
  4159.             $base       = $parts[ 0 ];
  4160.  
  4161.             switch( $base )
  4162.             {
  4163.                 case 'admin':
  4164.                     $basePath   = DISCUSS_ADMIN_ROOT;
  4165.                 break;
  4166.                 case 'site':
  4167.                 default:
  4168.                     $basePath   = DISCUSS_ROOT;
  4169.                 break;
  4170.             }
  4171.  
  4172.             // Replace / with proper directory structure.
  4173.             $path       = str_ireplace( '/' , DIRECTORY_SEPARATOR , $parts[ 1 ] );
  4174.  
  4175.             // Get the absolute path now.
  4176.             $path       = rtrim($basePath, '/') . '/' . $path . '.php';
  4177.  
  4178.             // Include the file now.
  4179.             include_once( $path );
  4180.  
  4181.             $locations[ $namespace ]    = true;
  4182.         }
  4183.  
  4184.         return true;
  4185.     }
  4186.  
  4187.     /**
  4188.      * Generates the query string for language selection.
  4189.      *
  4190.      * @since   4.0
  4191.      * @access  public
  4192.      * @param   string
  4193.      * @return
  4194.      */
  4195.     public static function getLanguageQuery($column = 'language')
  4196.     {
  4197.         $language = JFactory::getLanguage();
  4198.         $tag = $language->getTag();
  4199.         $query = '';
  4200.  
  4201.         $column = (!$column)? 'language' : $column;
  4202.  
  4203.         if (!empty($tag) && $tag != '*') {
  4204.             $db = ED::db();
  4205.             $query = ' (' . $db->qn($column) . '=' . $db->Quote($tag) . ' OR ' . $db->qn($column) . '=' . $db->Quote('') . ' OR ' . $db->qn($column) . '=' . $db->Quote('*') . ')';
  4206.         }
  4207.  
  4208.         return $query;
  4209.     }
  4210.  
  4211.     /**
  4212.      * Sets some callback data into the current session
  4213.      *
  4214.      * @since   1.0
  4215.      * @access  public
  4216.      * @param   string
  4217.      * @return
  4218.      */
  4219.     public static function setCallback($data)
  4220.     {
  4221.         $session = JFactory::getSession();
  4222.  
  4223.         // Serialize the callback data.
  4224.         $data = serialize( $data );
  4225.  
  4226.         // Store the profile type id into the session.
  4227.         $session->set('easydiscuss.callback', $data, 'com_easydiscuss');
  4228.     }
  4229.  
  4230.     /**
  4231.      * Retrieves stored callback data.
  4232.      *
  4233.      * @since   1.0
  4234.      * @access  public
  4235.      * @param   string
  4236.      * @return
  4237.      */
  4238.     public static function getCallback()
  4239.     {
  4240.         $session = JFactory::getSession();
  4241.         $data = $session->get('easydiscuss.callback', '', 'com_easydiscuss');
  4242.  
  4243.         $data = unserialize( $data );
  4244.  
  4245.         // Clear off the session once it's been picked up.
  4246.         $session->clear('easydiscuss.callback', 'com_easydiscuss');
  4247.  
  4248.         return $data;
  4249.     }
  4250.  
  4251.     /**
  4252.      * Retrieves external conversation link
  4253.      *
  4254.      * @since   4.0
  4255.      * @access  public
  4256.      * @param   string
  4257.      * @return
  4258.      */
  4259.     public static function getConversationsRoute()
  4260.     {  
  4261.         $config = ED::config();
  4262.        
  4263.         if (ED::easysocial()->exists() && $config->get('integration_easysocial_messaging')) {
  4264.             $link = ED::easysocial()->getConversationsRoute();
  4265.         }
  4266.  
  4267.         if (ED::jomsocial()->exists() && $config->get('integration_jomsocial_messaging')) {
  4268.             $link = ED::jomsocial()->getConversationsRoute();
  4269.         }
  4270.  
  4271.         return $link;
  4272.     }
  4273. }
  4274.  
  4275. // Backwards compatibility
  4276. class DiscussHelper extends ED {}
Add Comment
Please, Sign In to add comment