Source for file html.php

Documentation is available at html.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Libraries
  4.  * @subpackage  HTML
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7.  * @license     GNU General Public License version 2 or later; see LICENSE
  8.  */
  9.  
  10. defined('JPATH_PLATFORM'or die;
  11.  
  12. jimport('joomla.environment.browser');
  13. jimport('joomla.filesystem.file');
  14. jimport('joomla.filesystem.path');
  15. jimport('joomla.utilities.arrayhelper');
  16.  
  17. /**
  18.  * Utility class for all HTML drawing classes
  19.  *
  20.  * @package     Joomla.Libraries
  21.  * @subpackage  HTML
  22.  * @since       1.5
  23.  */
  24. abstract class JHtml
  25. {
  26.     /**
  27.      * Option values related to the generation of HTML output. Recognized
  28.      * options are:
  29.      *     fmtDepth, integer. The current indent depth.
  30.      *     fmtEol, string. The end of line string, default is linefeed.
  31.      *     fmtIndent, string. The string to use for indentation, default is
  32.      *     tab.
  33.      *
  34.      * @var    array 
  35.      * @since  1.5
  36.      */
  37.     public static $formatOptions array('format.depth' => 0'format.eol' => "\n"'format.indent' => "\t");
  38.  
  39.     /**
  40.      * An array to hold included paths
  41.      *
  42.      * @var    array 
  43.      * @since  1.5
  44.      */
  45.     protected static $includePaths array();
  46.  
  47.     /**
  48.      * An array to hold method references
  49.      *
  50.      * @var    array 
  51.      * @since  1.6
  52.      */
  53.     protected static $registry array();
  54.  
  55.     /**
  56.      * Method to extract a key
  57.      *
  58.      * @param   string  $key  The name of helper method to load, (prefix).(class).function
  59.      *                         prefix and class are optional and can be used to load custom html helpers.
  60.      *
  61.      * @return  array  Contains lowercase key, prefix, file, function.
  62.      *
  63.      * @since   1.6
  64.      */
  65.     protected static function extract($key)
  66.     {
  67.         $key preg_replace('#[^A-Z0-9_\.]#i'''$key);
  68.  
  69.         // Check to see whether we need to load a helper file
  70.         $parts explode('.'$key);
  71.  
  72.         $prefix (count($parts== array_shift($parts'JHtml');
  73.         $file (count($parts== array_shift($parts'');
  74.         $func array_shift($parts);
  75.  
  76.         return array(strtolower($prefix '.' $file '.' $func)$prefix$file$func);
  77.     }
  78.  
  79.     /**
  80.      * Class loader method
  81.      *
  82.      * Additional arguments may be supplied and are passed to the sub-class.
  83.      * Additional include paths are also able to be specified for third-party use
  84.      *
  85.      * @param   string  $key  The name of helper method to load, (prefix).(class).function
  86.      *                         prefix and class are optional and can be used to load custom
  87.      *                         html helpers.
  88.      *
  89.      * @return  mixed  JHtml::call($function, $args) or False on error
  90.      *
  91.      * @since   1.5
  92.      * @throws  InvalidArgumentException
  93.      */
  94.     public static function _($key)
  95.     {
  96.         list($key$prefix$file$funcstatic::extract($key);
  97.  
  98.         if (array_key_exists($keystatic::$registry))
  99.         {
  100.             $function static::$registry[$key];
  101.             $args func_get_args();
  102.  
  103.             // Remove function name from arguments
  104.             array_shift($args);
  105.  
  106.             return static::call($function$args);
  107.         }
  108.  
  109.         $className $prefix ucfirst($file);
  110.  
  111.         if (!class_exists($className))
  112.         {
  113.             $path JPath::find(static::$includePathsstrtolower($file'.php');
  114.  
  115.             if ($path)
  116.             {
  117.                 require_once $path;
  118.  
  119.                 if (!class_exists($className))
  120.                 {
  121.                     throw new InvalidArgumentException(sprintf('%s not found.'$className)500);
  122.                 }
  123.             }
  124.             else
  125.             {
  126.                 throw new InvalidArgumentException(sprintf('%s %s not found.'$prefix$file)500);
  127.             }
  128.         }
  129.  
  130.         $toCall array($className$func);
  131.  
  132.         if (is_callable($toCall))
  133.         {
  134.             static::register($key$toCall);
  135.             $args func_get_args();
  136.  
  137.             // Remove function name from arguments
  138.             array_shift($args);
  139.  
  140.             return static::call($toCall$args);
  141.         }
  142.         else
  143.         {
  144.             throw new InvalidArgumentException(sprintf('%s::%s not found.'$className$func)500);
  145.         }
  146.     }
  147.  
  148.     /**
  149.      * Registers a function to be called with a specific key
  150.      *
  151.      * @param   string  $key       The name of the key
  152.      * @param   string  $function  Function or method
  153.      *
  154.      * @return  boolean  True if the function is callable
  155.      *
  156.      * @since   1.6
  157.      */
  158.     public static function register($key$function)
  159.     {
  160.         list($keystatic::extract($key);
  161.  
  162.         if (is_callable($function))
  163.         {
  164.             static::$registry[$key$function;
  165.  
  166.             return true;
  167.         }
  168.  
  169.         return false;
  170.     }
  171.  
  172.     /**
  173.      * Removes a key for a method from registry.
  174.      *
  175.      * @param   string  $key  The name of the key
  176.      *
  177.      * @return  boolean  True if a set key is unset
  178.      *
  179.      * @since   1.6
  180.      */
  181.     public static function unregister($key)
  182.     {
  183.         list($keystatic::extract($key);
  184.  
  185.         if (isset(static::$registry[$key]))
  186.         {
  187.             unset(static::$registry[$key]);
  188.  
  189.             return true;
  190.         }
  191.  
  192.         return false;
  193.     }
  194.  
  195.     /**
  196.      * Test if the key is registered.
  197.      *
  198.      * @param   string  $key  The name of the key
  199.      *
  200.      * @return  boolean  True if the key is registered.
  201.      *
  202.      * @since   1.6
  203.      */
  204.     public static function isRegistered($key)
  205.     {
  206.         list($keystatic::extract($key);
  207.  
  208.         return isset(static::$registry[$key]);
  209.     }
  210.  
  211.     /**
  212.      * Function caller method
  213.      *
  214.      * @param   callable  $function  Function or method to call
  215.      * @param   array     $args      Arguments to be passed to function
  216.      *
  217.      * @return  mixed   Function result or false on error.
  218.      *
  219.      * @see     http://php.net/manual/en/function.call-user-func-array.php
  220.      * @since   1.6
  221.      * @throws  InvalidArgumentException
  222.      */
  223.     protected static function call($function$args)
  224.     {
  225.         if (!is_callable($function))
  226.         {
  227.             throw new InvalidArgumentException('Function not supported'500);
  228.         }
  229.  
  230.         // PHP 5.3 workaround
  231.         $temp array();
  232.  
  233.         foreach ($args as &$arg)
  234.         {
  235.             $temp[&$arg;
  236.         }
  237.  
  238.         return call_user_func_array($function$temp);
  239.     }
  240.  
  241.     /**
  242.      * Write a <a></a> element
  243.      *
  244.      * @param   string  $url      The relative URL to use for the href attribute
  245.      * @param   string  $text     The target attribute to use
  246.      * @param   array   $attribs  An associative array of attributes to add
  247.      *
  248.      * @return  string  <a></a> string
  249.      *
  250.      * @since   1.5
  251.      */
  252.     public static function link($url$text$attribs null)
  253.     {
  254.         if (is_array($attribs))
  255.         {
  256.             $attribs JArrayHelper::toString($attribs);
  257.         }
  258.  
  259.         return '<a href="' $url '" ' $attribs '>' $text '</a>';
  260.     }
  261.  
  262.     /**
  263.      * Write a <iframe></iframe> element
  264.      *
  265.      * @param   string  $url       The relative URL to use for the src attribute.
  266.      * @param   string  $name      The target attribute to use.
  267.      * @param   array   $attribs   An associative array of attributes to add.
  268.      * @param   string  $noFrames  The message to display if the iframe tag is not supported.
  269.      *
  270.      * @return  string  <iframe></iframe> element or message if not supported.
  271.      *
  272.      * @since   1.5
  273.      */
  274.     public static function iframe($url$name$attribs null$noFrames '')
  275.     {
  276.         if (is_array($attribs))
  277.         {
  278.             $attribs JArrayHelper::toString($attribs);
  279.         }
  280.  
  281.         return '<iframe src="' $url '" ' $attribs ' name="' $name '">' $noFrames '</iframe>';
  282.     }
  283.  
  284.     /**
  285.      * Compute the files to be included
  286.      *
  287.      * @param   string   $folder          folder name to search into (images, css, js, ...).
  288.      * @param   string   $file            path to file.
  289.      * @param   boolean  $relative        path to file is relative to /media folder  (and searches in template).
  290.      * @param   boolean  $detect_browser  detect browser to include specific browser files.
  291.      * @param   boolean  $detect_debug    detect debug to include compressed files if debug is on.
  292.      *
  293.      * @return  array    files to be included.
  294.      *
  295.      * @see     JBrowser
  296.      * @since   1.6
  297.      */
  298.     protected static function includeRelativeFiles($folder$file$relative$detect_browser$detect_debug)
  299.     {
  300.         // If http is present in filename
  301.         if (strpos($file'http'=== 0)
  302.         {
  303.             $includes array($file);
  304.         }
  305.         else
  306.         {
  307.             // Extract extension and strip the file
  308.             $strip JFile::stripExt($file);
  309.             $ext   JFile::getExt($file);
  310.  
  311.             // Prepare array of files
  312.             $includes array();
  313.  
  314.             // Detect browser and compute potential files
  315.             if ($detect_browser)
  316.             {
  317.                 $navigator JBrowser::getInstance();
  318.                 $browser $navigator->getBrowser();
  319.                 $major $navigator->getMajor();
  320.                 $minor $navigator->getMinor();
  321.  
  322.                 // Try to include files named filename.ext, filename_browser.ext, filename_browser_major.ext, filename_browser_major_minor.ext
  323.                 // where major and minor are the browser version names
  324.                 $potential array($strip$strip '_' $browser,  $strip '_' $browser '_' $major,
  325.                     $strip '_' $browser '_' $major '_' $minor);
  326.             }
  327.             else
  328.             {
  329.                 $potential array($strip);
  330.             }
  331.  
  332.             // If relative search in template directory or media directory
  333.             if ($relative)
  334.             {
  335.                 // Get the template
  336.                 $template JFactory::getApplication()->getTemplate();
  337.  
  338.                 // For each potential files
  339.                 foreach ($potential as $strip)
  340.                 {
  341.                     $files array();
  342.  
  343.                     // Detect debug mode
  344.                     if ($detect_debug && JFactory::getConfig()->get('debug'))
  345.                     {
  346.                         /*
  347.                          * Detect if we received a file in the format name.min.ext
  348.                          * If so, strip the .min part out, otherwise append -uncompressed
  349.                          */
  350.                         if (strrpos($strip'.min''-4'))
  351.                         {
  352.                             $position strrpos($strip'.min''-4');
  353.                             $filename str_replace('.min''.'$strip$position);
  354.                             $files[]  $filename $ext;
  355.                         }
  356.                         else
  357.                         {
  358.                             $files[$strip '-uncompressed.' $ext;
  359.                         }
  360.                     }
  361.  
  362.                     $files[$strip '.' $ext;
  363.  
  364.                     /*
  365.                      * Loop on 1 or 2 files and break on first found.
  366.                      * Add the content of the MD5SUM file located in the same folder to url to ensure cache browser refresh
  367.                      * This MD5SUM file must represent the signature of the folder content
  368.                      */
  369.                     foreach ($files as $file)
  370.                     {
  371.                         // If the file is in the template folder
  372.                         $path JPATH_THEMES "/$template/$folder/$file";
  373.  
  374.                         if (file_exists($path))
  375.                         {
  376.                             $md5 dirname($path'/MD5SUM';
  377.                             $includes[JUri::base(true"/templates/$template/$folder/$file.
  378.                                 (file_exists($md5('?' file_get_contents($md5)) '');
  379.  
  380.                             break;
  381.                         }
  382.                         else
  383.                         {
  384.                             // If the file contains any /: it can be in an media extension subfolder
  385.                             if (strpos($file'/'))
  386.                             {
  387.                                 // Divide the file extracting the extension as the first part before /
  388.                                 list($extension$fileexplode('/'$file2);
  389.  
  390.                                 // If the file yet contains any /: it can be a plugin
  391.                                 if (strpos($file'/'))
  392.                                 {
  393.                                     // Divide the file extracting the element as the first part before /
  394.                                     list($element$fileexplode('/'$file2);
  395.  
  396.                                     // Try to deal with plugins group in the media folder
  397.                                     $path JPATH_ROOT "/media/$extension/$element/$folder/$file";
  398.  
  399.                                     if (file_exists($path))
  400.                                     {
  401.                                         $md5 dirname($path'/MD5SUM';
  402.                                         $includes[JUri::root(true"/media/$extension/$element/$folder/$file.
  403.                                             (file_exists($md5('?' file_get_contents($md5)) '');
  404.  
  405.                                         break;
  406.                                     }
  407.  
  408.                                     // Try to deal with classical file in a a media subfolder called element
  409.                                     $path JPATH_ROOT "/media/$extension/$folder/$element/$file";
  410.  
  411.                                     if (file_exists($path))
  412.                                     {
  413.                                         $md5 dirname($path'/MD5SUM';
  414.                                         $includes[JUri::root(true"/media/$extension/$folder/$element/$file.
  415.                                             (file_exists($md5('?' file_get_contents($md5)) '');
  416.  
  417.                                         break;
  418.                                     }
  419.  
  420.                                     // Try to deal with system files in the template folder
  421.                                     $path JPATH_THEMES "/$template/$folder/system/$element/$file";
  422.  
  423.                                     if (file_exists($path))
  424.                                     {
  425.                                         $md5 dirname($path'/MD5SUM';
  426.                                         $includes[JUri::root(true"/templates/$template/$folder/system/$element/$file.
  427.                                             (file_exists($md5('?' file_get_contents($md5)) '');
  428.  
  429.                                         break;
  430.                                     }
  431.  
  432.                                     // Try to deal with system files in the media folder
  433.                                     $path JPATH_ROOT "/media/system/$folder/$element/$file";
  434.  
  435.                                     if (file_exists($path))
  436.                                     {
  437.                                         $md5 dirname($path'/MD5SUM';
  438.                                         $includes[JUri::root(true"/media/system/$folder/$element/$file.
  439.                                             (file_exists($md5('?' file_get_contents($md5)) '');
  440.  
  441.                                         break;
  442.                                     }
  443.                                 }
  444.                                 else
  445.                                 {
  446.                                     // Try to deals in the extension media folder
  447.                                     $path JPATH_ROOT "/media/$extension/$folder/$file";
  448.  
  449.                                     if (file_exists($path))
  450.                                     {
  451.                                         $md5 dirname($path'/MD5SUM';
  452.                                         $includes[JUri::root(true"/media/$extension/$folder/$file.
  453.                                             (file_exists($md5('?' file_get_contents($md5)) '');
  454.  
  455.                                         break;
  456.                                     }
  457.  
  458.                                     // Try to deal with system files in the template folder
  459.                                     $path JPATH_THEMES "/$template/$folder/system/$file";
  460.  
  461.                                     if (file_exists($path))
  462.                                     {
  463.                                         $md5 dirname($path'/MD5SUM';
  464.                                         $includes[JUri::root(true"/templates/$template/$folder/system/$file.
  465.                                             (file_exists($md5('?' file_get_contents($md5)) '');
  466.  
  467.                                         break;
  468.                                     }
  469.  
  470.                                     // Try to deal with system files in the media folder
  471.                                     $path JPATH_ROOT "/media/system/$folder/$file";
  472.  
  473.                                     if (file_exists($path))
  474.                                     {
  475.                                         $md5 dirname($path'/MD5SUM';
  476.                                         $includes[JUri::root(true"/media/system/$folder/$file.
  477.                                             (file_exists($md5('?' file_get_contents($md5)) '');
  478.  
  479.                                         break;
  480.                                     }
  481.                                 }
  482.                             }
  483.                             // Try to deal with system files in the media folder
  484.                             else
  485.                             {
  486.                                 $path JPATH_ROOT "/media/system/$folder/$file";
  487.  
  488.                                 if (file_exists($path))
  489.                                 {
  490.                                     $md5 dirname($path'/MD5SUM';
  491.                                     $includes[JUri::root(true"/media/system/$folder/$file.
  492.                                             (file_exists($md5('?' file_get_contents($md5)) '');
  493.  
  494.                                     break;
  495.                                 }
  496.                             }
  497.                         }
  498.                     }
  499.                 }
  500.             }
  501.             // If not relative and http is not present in filename
  502.             else
  503.             {
  504.                 foreach ($potential as $strip)
  505.                 {
  506.                     $files array();
  507.  
  508.                     // Detect debug mode
  509.                     if ($detect_debug && JFactory::getConfig()->get('debug'))
  510.                     {
  511.                         /*
  512.                          * Detect if we received a file in the format name.min.ext
  513.                          * If so, strip the .min part out, otherwise append -uncompressed
  514.                          */
  515.                         if (strrpos($strip'.min''-4'))
  516.                         {
  517.                             $position strrpos($strip'.min''-4');
  518.                             $filename str_replace('.min''.'$strip$position);
  519.                             $files[]  $filename $ext;
  520.                         }
  521.                         else
  522.                         {
  523.                             $files[$strip '-uncompressed.' $ext;
  524.                         }
  525.                     }
  526.  
  527.                     $files[$strip '.' $ext;
  528.  
  529.                     /*
  530.                      * Loop on 1 or 2 files and break on first found.
  531.                      * Add the content of the MD5SUM file located in the same folder to url to ensure cache browser refresh
  532.                      * This MD5SUM file must represent the signature of the folder content
  533.                      */
  534.                     foreach ($files as $file)
  535.                     {
  536.                         $path JPATH_ROOT "/$file";
  537.  
  538.                         if (file_exists($path))
  539.                         {
  540.                             $md5 dirname($path'/MD5SUM';
  541.                             $includes[JUri::root(true"/$file.
  542.                                 (file_exists($md5('?' file_get_contents($md5)) '');
  543.  
  544.                             break;
  545.                         }
  546.                     }
  547.                 }
  548.             }
  549.         }
  550.  
  551.         return $includes;
  552.     }
  553.  
  554.     /**
  555.      * Write a <img></img> element
  556.      *
  557.      * @param   string   $file      The relative or absolute URL to use for the src attribute.
  558.      * @param   string   $alt       The alt text.
  559.      * @param   mixed    $attribs   String or associative array of attribute(s) to use.
  560.      * @param   boolean  $relative  Path to file is relative to /media folder (and searches in template).
  561.      * @param   mixed    $path_rel  Return html tag without (-1) or with file computing(false). Return computed path only (true).
  562.      *
  563.      * @return  string 
  564.      *
  565.      * @since   1.5
  566.      */
  567.     public static function image($file$alt$attribs null$relative false$path_rel false)
  568.     {
  569.         if ($path_rel !== -1)
  570.         {
  571.             $includes static::includeRelativeFiles('images'$file$relativefalsefalse);
  572.             $file count($includes$includes[0null;
  573.         }
  574.  
  575.         // If only path is required
  576.         if ($path_rel)
  577.         {
  578.             return $file;
  579.         }
  580.         else
  581.         {
  582.             return '<img src="' $file '" alt="' $alt '" '
  583.             . trim((is_array($attribsJArrayHelper::toString($attribs$attribs' /')
  584.             . '>';
  585.         }
  586.     }
  587.  
  588.     /**
  589.      * Write a <link rel="stylesheet" style="text/css" /> element
  590.      *
  591.      * @param   string   $file            path to file
  592.      * @param   array    $attribs         attributes to be added to the stylesheet
  593.      * @param   boolean  $relative        path to file is relative to /media folder
  594.      * @param   boolean  $path_only       return the path to the file only
  595.      * @param   boolean  $detect_browser  detect browser to include specific browser css files
  596.      *                                     will try to include file, file_*browser*, file_*browser*_*major*, file_*browser*_*major*_*minor*
  597.      *                                     <table>
  598.      *                                        <tr><th>Navigator</th>                  <th>browser</th>    <th>major.minor</th></tr>
  599.      *
  600.      *                                        <tr><td>Safari 3.0.x</td>               <td>konqueror</td>    <td>522.x</td></tr>
  601.      *                                        <tr><td>Safari 3.1.x and 3.2.x</td>     <td>konqueror</td>    <td>525.x</td></tr>
  602.      *                                        <tr><td>Safari 4.0 to 4.0.2</td>        <td>konqueror</td>    <td>530.x</td></tr>
  603.      *                                        <tr><td>Safari 4.0.3 to 4.0.4</td>      <td>konqueror</td>    <td>531.x</td></tr>
  604.      *                                        <tr><td>iOS 4.0 Safari</td>             <td>konqueror</td>    <td>532.x</td></tr>
  605.      *                                        <tr><td>Safari 5.0</td>                 <td>konqueror</td>    <td>533.x</td></tr>
  606.      *
  607.      *                                        <tr><td>Google Chrome 1.0</td>          <td>konqueror</td>    <td>528.x</td></tr>
  608.      *                                        <tr><td>Google Chrome 2.0</td>          <td>konqueror</td>    <td>530.x</td></tr>
  609.      *                                        <tr><td>Google Chrome 3.0 and 4.x</td>  <td>konqueror</td>    <td>532.x</td></tr>
  610.      *                                        <tr><td>Google Chrome 5.0</td>          <td>konqueror</td>    <td>533.x</td></tr>
  611.      *
  612.      *                                        <tr><td>Internet Explorer 5.5</td>      <td>msie</td>        <td>5.5</td></tr>
  613.      *                                        <tr><td>Internet Explorer 6.x</td>      <td>msie</td>        <td>6.x</td></tr>
  614.      *                                        <tr><td>Internet Explorer 7.x</td>      <td>msie</td>        <td>7.x</td></tr>
  615.      *                                        <tr><td>Internet Explorer 8.x</td>      <td>msie</td>        <td>8.x</td></tr>
  616.      *
  617.      *                                        <tr><td>Firefox</td>                    <td>mozilla</td>    <td>5.0</td></tr>
  618.      *                                     </table>
  619.      *                                     a lot of others
  620.      * @param   boolean  $detect_debug    detect debug to search for compressed files if debug is on
  621.      *
  622.      * @return  mixed  nothing if $path_only is false, null, path or array of path if specific css browser files were detected
  623.      *
  624.      * @see     JBrowser
  625.      * @since   1.5
  626.      */
  627.     public static function stylesheet($file$attribs array()$relative false$path_only false$detect_browser true$detect_debug true)
  628.     {
  629.         $includes static::includeRelativeFiles('css'$file$relative$detect_browser$detect_debug);
  630.  
  631.         // If only path is required
  632.         if ($path_only)
  633.         {
  634.             if (count($includes== 0)
  635.             {
  636.                 return null;
  637.             }
  638.             elseif (count($includes== 1)
  639.             {
  640.                 return $includes[0];
  641.             }
  642.             else
  643.             {
  644.                 return $includes;
  645.             }
  646.         }
  647.         // If inclusion is required
  648.         else
  649.         {
  650.             $document JFactory::getDocument();
  651.  
  652.             foreach ($includes as $include)
  653.             {
  654.                 $document->addStylesheet($include'text/css'null$attribs);
  655.             }
  656.         }
  657.     }
  658.  
  659.     /**
  660.      * Write a <script></script> element
  661.      *
  662.      * @param   string   $file            path to file.
  663.      * @param   boolean  $framework       load the JS framework.
  664.      * @param   boolean  $relative        path to file is relative to /media folder.
  665.      * @param   boolean  $path_only       return the path to the file only.
  666.      * @param   boolean  $detect_browser  detect browser to include specific browser js files.
  667.      * @param   boolean  $detect_debug    detect debug to search for compressed files if debug is on.
  668.      *
  669.      * @return  mixed  nothing if $path_only is false, null, path or array of path if specific js browser files were detected.
  670.      *
  671.      * @see     JHtml::stylesheet()
  672.      * @since   1.5
  673.      */
  674.     public static function script($file$framework false$relative false$path_only false$detect_browser true$detect_debug true)
  675.     {
  676.         // Include MooTools framework
  677.         if ($framework)
  678.         {
  679.             static::_('behavior.framework');
  680.         }
  681.  
  682.         $includes static::includeRelativeFiles('js'$file$relative$detect_browser$detect_debug);
  683.  
  684.         // If only path is required
  685.         if ($path_only)
  686.         {
  687.             if (count($includes== 0)
  688.             {
  689.                 return null;
  690.             }
  691.             elseif (count($includes== 1)
  692.             {
  693.                 return $includes[0];
  694.             }
  695.             else
  696.             {
  697.                 return $includes;
  698.             }
  699.         }
  700.         // If inclusion is required
  701.         else
  702.         {
  703.             $document JFactory::getDocument();
  704.  
  705.             foreach ($includes as $include)
  706.             {
  707.                 $document->addScript($include);
  708.             }
  709.         }
  710.     }
  711.  
  712.     /**
  713.      * Set format related options.
  714.      *
  715.      * Updates the formatOptions array with all valid values in the passed array.
  716.      *
  717.      * @param   array  $options  Option key/value pairs.
  718.      *
  719.      * @return  void 
  720.      *
  721.      * @see     JHtml::$formatOptions
  722.      * @since   1.5
  723.      */
  724.     public static function setFormatOptions($options)
  725.     {
  726.         foreach ($options as $key => $val)
  727.         {
  728.             if (isset(static::$formatOptions[$key]))
  729.             {
  730.                 static::$formatOptions[$key$val;
  731.             }
  732.         }
  733.     }
  734.  
  735.     /**
  736. /**
  737.      * Returns formated date according to a given format and time zone.
  738.      *
  739.      * @param   string   $input      String in a format accepted by date(), defaults to "now".
  740.      * @param   string   $format     The date format specification string (see {@link PHP_MANUAL#date}).
  741.      * @param   mixed    $tz         Time zone to be used for the date.  Special cases: boolean true for user
  742.      *                                setting, boolean false for server setting.
  743.      * @param   boolean  $gregorian  True to use Gregorian calendar.
  744.      *
  745.      * @return  string    A date translated by the given format and time zone.
  746.      *
  747.      * @see     strftime
  748.      * @since   1.5
  749.      */
  750.     public static function date($input 'now'$format null$tz true$gregorian false)
  751.     {
  752.         // Get some system objects.
  753.         $config JFactory::getConfig();
  754.         $user JFactory::getUser();
  755.  
  756.         // UTC date converted to user time zone.
  757.         if ($tz === true)
  758.         {
  759.             // Get a date object based on UTC.
  760.             $date JFactory::getDate($input'UTC');
  761.  
  762.             // Set the correct time zone based on the user configuration.
  763.             $date->setTimeZone(new DateTimeZone($user->getParam('timezone'$config->get('offset'))));
  764.         }
  765.         // UTC date converted to server time zone.
  766.         elseif ($tz === false)
  767.         {
  768.             // Get a date object based on UTC.
  769.             $date JFactory::getDate($input'UTC');
  770.  
  771.             // Set the correct time zone based on the server configuration.
  772.             $date->setTimeZone(new DateTimeZone($config->get('offset')));
  773.         }
  774.         // No date conversion.
  775.         elseif ($tz === null)
  776.         {
  777.             $date JFactory::getDate($input);
  778.         }
  779.         // UTC date converted to given time zone.
  780.         else
  781.         {
  782.             // Get a date object based on UTC.
  783.             $date JFactory::getDate($input'UTC');
  784.  
  785.             // Set the correct time zone based on the server configuration.
  786.             $date->setTimeZone(new DateTimeZone($tz));
  787.         }
  788.  
  789.         // If no format is given use the default locale based format.
  790.         if (!$format)
  791.         {
  792.             $format JText::_('DATE_FORMAT_LC1');
  793.         }
  794.         // $format is an existing language key
  795.         elseif (JFactory::getLanguage()->hasKey($format))
  796.         {
  797.             $format JText::_($format);
  798.         }
  799.  
  800.         if ($gregorian)
  801.         {
  802.             return $date->format($formattrue);
  803.         }
  804.         else
  805.         {
  806.             return $date->calendar($formattrue);
  807.         }
  808.     }
  809.  
  810.     /**
  811.      * Creates a tooltip with an image as button
  812.      *
  813.      * @param   string  $tooltip  The tip string.
  814.      * @param   mixed   $title    The title of the tooltip or an associative array with keys contained in
  815.      *                             {'title','image','text','href','alt'} and values corresponding to parameters of the same name.
  816.      * @param   string  $image    The image for the tip, if no text is provided.
  817.      * @param   string  $text     The text for the tip.
  818.      * @param   string  $href     An URL that will be used to create the link.
  819.      * @param   string  $alt      The alt attribute for img tag.
  820.      * @param   string  $class    CSS class for the tool tip.
  821.      *
  822.      * @return  string 
  823.      *
  824.      * @since   1.5
  825.      */
  826.     public static function tooltip($tooltip$title ''$image 'tooltip.png'$text ''$href ''$alt 'Tooltip'$class 'hasTooltip')
  827.     {
  828.         if (is_array($title))
  829.         {
  830.             foreach (array('image''text''href''alt''class'as $param)
  831.             {
  832.                 if (isset($title[$param]))
  833.                 {
  834.                     $$param $title[$param];
  835.                 }
  836.             }
  837.  
  838.             if (isset($title['title']))
  839.             {
  840.                 $title $title['title'];
  841.             }
  842.             else
  843.             {
  844.                 $title '';
  845.             }
  846.         }
  847.  
  848.         if (!$text)
  849.         {
  850.             $alt htmlspecialchars($altENT_COMPAT'UTF-8');
  851.             $text static::image($image$altnulltrue);
  852.         }
  853.  
  854.         if ($href)
  855.         {
  856.             $tip '<a href="' $href '">' $text '</a>';
  857.         }
  858.         else
  859.         {
  860.             $tip $text;
  861.         }
  862.  
  863.         if ($class == 'hasTip')
  864.         {
  865.             // Still using MooTools tooltips!
  866.             $tooltip htmlspecialchars($tooltipENT_COMPAT'UTF-8');
  867.  
  868.             if ($title)
  869.             {
  870.                 $title htmlspecialchars($titleENT_COMPAT'UTF-8');
  871.                 $tooltip $title '::' $tooltip;
  872.             }
  873.         }
  874.         else
  875.         {
  876.             $tooltip self::tooltipText($title$tooltip0);
  877.         }
  878.  
  879.         return '<span class="' $class '" title="' $tooltip '">' $tip '</span>';
  880.     }
  881.  
  882.     /**
  883.      * Converts a double colon seperated string or 2 separate strings to a string ready for bootstrap tooltips
  884.      *
  885.      * @param   string  $title      The title of the tooltip (or combined '::' separated string).
  886.      * @param   string  $content    The content to tooltip.
  887.      * @param   int     $translate  If true will pass texts through JText.
  888.      * @param   int     $escape     If true will pass texts through htmlspecialchars.
  889.      *
  890.      * @return  string  The tooltip string
  891.      *
  892.      * @since   3.1.2
  893.      */
  894.     public static function tooltipText($title ''$content ''$translate 1$escape 1)
  895.     {
  896.         // Return empty in no title or content is given.
  897.         if ($title == '' && $content == '')
  898.         {
  899.             return '';
  900.         }
  901.  
  902.         // Split title into title and content if the title contains '::' (old Mootools format).
  903.         if ($content == '' && !(strpos($title'::'=== false))
  904.         {
  905.             list($title$contentexplode('::'$title2);
  906.         }
  907.  
  908.         // Pass texts through the JText.
  909.         if ($translate)
  910.         {
  911.             $title JText::_($title);
  912.             $content JText::_($content);
  913.         }
  914.  
  915.         // Escape the texts.
  916.         if ($escape)
  917.         {
  918.             $title str_replace('"''&quot;'$title);
  919.             $content str_replace('"''&quot;'$content);
  920.         }
  921.  
  922.         // Return only the content if no title is given.
  923.         if ($title == '')
  924.         {
  925.             return $content;
  926.         }
  927.  
  928.         // Return only the title if title and text are the same.
  929.         if ($title == $content)
  930.         {
  931.             return '<strong>' $title '</strong>';
  932.         }
  933.  
  934.         // Return the formated sting combining the title and  content.
  935.         if ($content != '')
  936.         {
  937.             return '<strong>' $title '</strong><br />' $content;
  938.         }
  939.  
  940.         // Return only the title.
  941.         return $title;
  942.     }
  943.  
  944.     /**
  945.      * Displays a calendar control field
  946.      *
  947.      * @param   string  $value    The date value
  948.      * @param   string  $name     The name of the text field
  949.      * @param   string  $id       The id of the text field
  950.      * @param   string  $format   The date format
  951.      * @param   array   $attribs  Additional HTML attributes
  952.      *
  953.      * @return  string  HTML markup for a calendar field
  954.      *
  955.      * @since   1.5
  956.      */
  957.     public static function calendar($value$name$id$format '%Y-%m-%d'$attribs null)
  958.     {
  959.         static $done;
  960.  
  961.         if ($done === null)
  962.         {
  963.             $done array();
  964.         }
  965.  
  966.         $attribs['class'= isset($attribs['class']$attribs['class''input-medium';
  967.         $attribs['class'trim($attribs['class'' hasTooltip');
  968.  
  969.         $readonly = isset($attribs['readonly']&& $attribs['readonly'== 'readonly';
  970.         $disabled = isset($attribs['disabled']&& $attribs['disabled'== 'disabled';
  971.  
  972.         if (is_array($attribs))
  973.         {
  974.             $attribs JArrayHelper::toString($attribs);
  975.         }
  976.  
  977.         static::_('bootstrap.tooltip');
  978.  
  979.         if (!$readonly && !$disabled)
  980.         {
  981.             // Load the calendar behavior
  982.             static::_('behavior.calendar');
  983.  
  984.             // Only display the triggers once for each control.
  985.             if (!in_array($id$done))
  986.             {
  987.                 $document JFactory::getDocument();
  988.                 $document
  989.                     ->addScriptDeclaration(
  990.                     'window.addEvent(\'domready\', function() {Calendar.setup({
  991.                 // Id of the input field
  992.                 inputField: "' $id '",
  993.                 // Format of the input field
  994.                 ifFormat: "' $format '",
  995.                 // Trigger for the calendar (button ID)
  996.                 button: "' $id '_img",
  997.                 // Alignment (defaults to "Bl")
  998.                 align: "Tl",
  999.                 singleClick: true,
  1000.                 firstDay: ' JFactory::getLanguage()->getFirstDay('
  1001.                 });});'
  1002.                 );
  1003.                 $done[$id;
  1004.             }
  1005.  
  1006.             return '<div class="input-append"><input type="text" title="' (!== (int) $value static::_('date'$valuenullnull'')
  1007.                 . '" name="' $name '" id="' $id '" value="' htmlspecialchars($valueENT_COMPAT'UTF-8''" ' $attribs ' />'
  1008.                 . '<button type="button" class="btn" id="' $id '_img"><i class="icon-calendar"></i></button></div>';
  1009.         }
  1010.         else
  1011.         {
  1012.             return '<input type="text" title="' (!== (int) $value static::_('date'$valuenullnull'')
  1013.                 . '" value="' (!== (int) $value static::_('date'$value'Y-m-d H:i:s'null'''" ' $attribs
  1014.                 . ' /><input type="hidden" name="' $name '" id="' $id '" value="' htmlspecialchars($valueENT_COMPAT'UTF-8''" />';
  1015.         }
  1016.     }
  1017.  
  1018.     /**
  1019.      * Add a directory where JHtml should search for helpers. You may
  1020.      * either pass a string or an array of directories.
  1021.      *
  1022.      * @param   string  $path  A path to search.
  1023.      *
  1024.      * @return  array  An array with directory elements
  1025.      *
  1026.      * @since   1.5
  1027.      */
  1028.     public static function addIncludePath($path '')
  1029.     {
  1030.         // Force path to array
  1031.         settype($path'array');
  1032.  
  1033.         // Loop through the path directories
  1034.         foreach ($path as $dir)
  1035.         {
  1036.             if (!empty($dir&& !in_array($dirstatic::$includePaths))
  1037.             {
  1038.                 array_unshift(static::$includePathsJPath::clean($dir));
  1039.             }
  1040.         }
  1041.  
  1042.         return static::$includePaths;
  1043.     }
  1044.  
  1045.     /**
  1046.      * Internal method to get a JavaScript object notation string from an array
  1047.      *
  1048.      * @param   array  $array  The array to convert to JavaScript object notation
  1049.      *
  1050.      * @return  string  JavaScript object notation representation of the array
  1051.      *
  1052.      * @since   3.0
  1053.      */
  1054.     public static function getJSObject(array $array array())
  1055.     {
  1056.         $elements array();
  1057.  
  1058.         foreach ($array as $k => $v)
  1059.         {
  1060.             // Don't encode either of these types
  1061.             if (is_null($v|| is_resource($v))
  1062.             {
  1063.                 continue;
  1064.             }
  1065.  
  1066.             // Safely encode as a Javascript string
  1067.             $key json_encode((string) $k);
  1068.  
  1069.             if (is_bool($v))
  1070.             {
  1071.                 $elements[$key ': ' ($v 'true' 'false');
  1072.             }
  1073.             elseif (is_numeric($v))
  1074.             {
  1075.                 $elements[$key ': ' ($v 0);
  1076.             }
  1077.             elseif (is_string($v))
  1078.             {
  1079.                 if (strpos($v'\\'=== 0)
  1080.                 {
  1081.                     // Items such as functions and JSON objects are prefixed with \, strip the prefix and don't encode them
  1082.                     $elements[$key ': ' substr($v1);
  1083.                 }
  1084.                 else
  1085.                 {
  1086.                     // The safest way to insert a string
  1087.                     $elements[$key ': ' json_encode((string) $v);
  1088.                 }
  1089.             }
  1090.             else
  1091.             {
  1092.                 $elements[$key ': ' static::getJSObject(is_object($vget_object_vars($v$v);
  1093.             }
  1094.         }
  1095.  
  1096.         return '{' implode(','$elements'}';
  1097.     }
  1098. }

Documentation generated on Tue, 19 Nov 2013 15:04:51 +0100 by phpDocumentor 1.4.3