1 <?php
2 /**
3 * @package FrameworkOnFramework
4 * @subpackage platform
5 * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
6 * @license GNU General Public License version 2 or later; see LICENSE.txt
7 */
8 // Protect from unauthorized access
9 defined('FOF_INCLUDED') or die;
10
11 /**
12 * Part of the FOF Platform Abstraction Layer.
13 *
14 * This implements the platform class for Joomla! 2.5 or later
15 *
16 * @package FrameworkOnFramework
17 * @since 2.1
18 */
19 class FOFIntegrationJoomlaPlatform extends FOFPlatform implements FOFPlatformInterface
20 {
21 /**
22 * The table and table field cache object, used to speed up database access
23 *
24 * @var JRegistry|null
25 */
26 private $_cache = null;
27
28 /**
29 * Public constructor
30 */
31 public function __construct()
32 {
33 $this->name = 'joomla';
34 $this->humanReadableName = 'Joomla!';
35 $this->version = defined('JVERSION') ? JVERSION : '0.0';
36 }
37
38 /**
39 * Checks if the current script is run inside a valid CMS execution
40 *
41 * @see FOFPlatformInterface::checkExecution()
42 *
43 * @return bool
44 */
45 public function checkExecution()
46 {
47 return defined('_JEXEC');
48 }
49
50 public function raiseError($code, $message)
51 {
52 if (version_compare($this->version, '3.0', 'ge'))
53 {
54 throw new Exception($message, $code);
55 }
56 else
57 {
58 return JError::raiseError($code, $message);
59 }
60 }
61
62 /**
63 * Is this platform enabled?
64 *
65 * @see FOFPlatformInterface::isEnabled()
66 *
67 * @return boolean
68 */
69 public function isEnabled()
70 {
71 if (is_null($this->isEnabled))
72 {
73 $this->isEnabled = true;
74
75 // Make sure _JEXEC is defined
76 if (!defined('_JEXEC'))
77 {
78 $this->isEnabled = false;
79 }
80
81 // We need JVERSION to be defined
82 if ($this->isEnabled)
83 {
84 if (!defined('JVERSION'))
85 {
86 $this->isEnabled = false;
87 }
88 }
89
90 // Check if JFactory exists
91 if ($this->isEnabled)
92 {
93 if (!class_exists('JFactory'))
94 {
95 $this->isEnabled = false;
96 }
97 }
98
99 // Check if JApplication exists
100 if ($this->isEnabled)
101 {
102 $appExists = class_exists('JApplication');
103 $appExists = $appExists || class_exists('JCli');
104 $appExists = $appExists || class_exists('JApplicationCli');
105
106 if (!$appExists)
107 {
108 $this->isEnabled = false;
109 }
110 }
111 }
112
113 return $this->isEnabled;
114 }
115
116 /**
117 * Main function to detect if we're running in a CLI environment and we're admin
118 *
119 * @return array isCLI and isAdmin. It's not an associtive array, so we can use list.
120 */
121 protected function isCliAdmin()
122 {
123 static $isCLI = null;
124 static $isAdmin = null;
125
126 if (is_null($isCLI) && is_null($isAdmin))
127 {
128 try
129 {
130 if (is_null(JFactory::$application))
131 {
132 $isCLI = true;
133 }
134 else
135 {
136 $app = JFactory::getApplication();
137 $isCLI = $app instanceof JException || $app instanceof JApplicationCli;
138 }
139 }
140 catch (Exception $e)
141 {
142 $isCLI = true;
143 }
144
145 if ($isCLI)
146 {
147 $isAdmin = false;
148 }
149 else
150 {
151 $isAdmin = !JFactory::$application ? false : JFactory::getApplication()->isAdmin();
152 }
153 }
154
155 return array($isCLI, $isAdmin);
156 }
157
158 /**
159 * Returns absolute path to directories used by the CMS.
160 *
161 * @see FOFPlatformInterface::getPlatformBaseDirs()
162 *
163 * @return array A hash array with keys root, public, admin, tmp and log.
164 */
165 public function getPlatformBaseDirs()
166 {
167 return array(
168 'root' => JPATH_ROOT,
169 'public' => JPATH_SITE,
170 'admin' => JPATH_ADMINISTRATOR,
171 'tmp' => JFactory::getConfig()->get('tmp_dir'),
172 'log' => JFactory::getConfig()->get('log_dir')
173 );
174 }
175
176 /**
177 * Returns the base (root) directories for a given component.
178 *
179 * @param string $component The name of the component. For Joomla! this
180 * is something like "com_example"
181 *
182 * @see FOFPlatformInterface::getComponentBaseDirs()
183 *
184 * @return array A hash array with keys main, alt, site and admin.
185 */
186 public function getComponentBaseDirs($component)
187 {
188 if ($this->isFrontend())
189 {
190 $mainPath = JPATH_SITE . '/components/' . $component;
191 $altPath = JPATH_ADMINISTRATOR . '/components/' . $component;
192 }
193 else
194 {
195 $mainPath = JPATH_ADMINISTRATOR . '/components/' . $component;
196 $altPath = JPATH_SITE . '/components/' . $component;
197 }
198
199 return array(
200 'main' => $mainPath,
201 'alt' => $altPath,
202 'site' => JPATH_SITE . '/components/' . $component,
203 'admin' => JPATH_ADMINISTRATOR . '/components/' . $component,
204 );
205 }
206
207 /**
208 * Return a list of the view template paths for this component.
209 *
210 * @param string $component The name of the component. For Joomla! this
211 * is something like "com_example"
212 * @param string $view The name of the view you're looking a
213 * template for
214 * @param string $layout The layout name to load, e.g. 'default'
215 * @param string $tpl The sub-template name to load (null by default)
216 * @param boolean $strict If true, only the specified layout will be searched for.
217 * Otherwise we'll fall back to the 'default' layout if the
218 * specified layout is not found.
219 *
220 * @see FOFPlatformInterface::getViewTemplateDirs()
221 *
222 * @return array
223 */
224 public function getViewTemplatePaths($component, $view, $layout = 'default', $tpl = null, $strict = false)
225 {
226 $isAdmin = $this->isBackend();
227
228 $basePath = $isAdmin ? 'admin:' : 'site:';
229 $basePath .= $component . '/';
230 $altBasePath = $basePath;
231 $basePath .= $view . '/';
232 $altBasePath .= (FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view)) . '/';
233
234 if ($strict)
235 {
236 $paths = array(
237 $basePath . $layout . ($tpl ? "_$tpl" : ''),
238 $altBasePath . $layout . ($tpl ? "_$tpl" : ''),
239 );
240 }
241 else
242 {
243 $paths = array(
244 $basePath . $layout . ($tpl ? "_$tpl" : ''),
245 $basePath . $layout,
246 $basePath . 'default' . ($tpl ? "_$tpl" : ''),
247 $basePath . 'default',
248 $altBasePath . $layout . ($tpl ? "_$tpl" : ''),
249 $altBasePath . $layout,
250 $altBasePath . 'default' . ($tpl ? "_$tpl" : ''),
251 $altBasePath . 'default',
252 );
253 $paths = array_unique($paths);
254 }
255
256 return $paths;
257 }
258
259 /**
260 * Get application-specific suffixes to use with template paths. This allows
261 * you to look for view template overrides based on the application version.
262 *
263 * @return array A plain array of suffixes to try in template names
264 */
265 public function getTemplateSuffixes()
266 {
267 $jversion = new JVersion;
268 $versionParts = explode('.', $jversion->RELEASE);
269 $majorVersion = array_shift($versionParts);
270 $suffixes = array(
271 '.j' . str_replace('.', '', $jversion->getHelpVersion()),
272 '.j' . $majorVersion,
273 );
274
275 return $suffixes;
276 }
277
278 /**
279 * Return the absolute path to the application's template overrides
280 * directory for a specific component. We will use it to look for template
281 * files instead of the regular component directorues. If the application
282 * does not have such a thing as template overrides return an empty string.
283 *
284 * @param string $component The name of the component for which to fetch the overrides
285 * @param boolean $absolute Should I return an absolute or relative path?
286 *
287 * @return string The path to the template overrides directory
288 */
289 public function getTemplateOverridePath($component, $absolute = true)
290 {
291 list($isCli, $isAdmin) = $this->isCliAdmin();
292
293 if (!$isCli)
294 {
295 if ($absolute)
296 {
297 $path = JPATH_THEMES . '/';
298 }
299 else
300 {
301 $path = $isAdmin ? 'administrator/templates/' : 'templates/';
302 }
303
304 if (substr($component, 0, 7) == 'media:/')
305 {
306 $directory = 'media/' . substr($component, 7);
307 }
308 else
309 {
310 $directory = 'html/' . $component;
311 }
312
313 $path .= JFactory::getApplication()->getTemplate() .
314 '/' . $directory;
315 }
316 else
317 {
318 $path = '';
319 }
320
321 return $path;
322 }
323
324 /**
325 * Load the translation files for a given component.
326 *
327 * @param string $component The name of the component. For Joomla! this
328 * is something like "com_example"
329 *
330 * @see FOFPlatformInterface::loadTranslations()
331 *
332 * @return void
333 */
334 public function loadTranslations($component)
335 {
336 if ($this->isBackend())
337 {
338 $paths = array(JPATH_ROOT, JPATH_ADMINISTRATOR);
339 }
340 else
341 {
342 $paths = array(JPATH_ADMINISTRATOR, JPATH_ROOT);
343 }
344
345 $jlang = JFactory::getLanguage();
346 $jlang->load($component, $paths[0], 'en-GB', true);
347 $jlang->load($component, $paths[0], null, true);
348 $jlang->load($component, $paths[1], 'en-GB', true);
349 $jlang->load($component, $paths[1], null, true);
350 }
351
352 /**
353 * Authorise access to the component in the back-end.
354 *
355 * @param string $component The name of the component.
356 *
357 * @see FOFPlatformInterface::authorizeAdmin()
358 *
359 * @return boolean True to allow loading the component, false to halt loading
360 */
361 public function authorizeAdmin($component)
362 {
363 if ($this->isBackend())
364 {
365 // Master access check for the back-end, Joomla! 1.6 style.
366 $user = JFactory::getUser();
367
368 if (!$user->authorise('core.manage', $component)
369 && !$user->authorise('core.admin', $component))
370 {
371 return false;
372 }
373 }
374
375 return true;
376 }
377
378 /**
379 * Return a user object.
380 *
381 * @param integer $id The user ID to load. Skip or use null to retrieve
382 * the object for the currently logged in user.
383 *
384 * @see FOFPlatformInterface::getUser()
385 *
386 * @return JUser The JUser object for the specified user
387 */
388 public function getUser($id = null)
389 {
390 return JFactory::getUser($id);
391 }
392
393 /**
394 * Returns the JDocument object which handles this component's response.
395 *
396 * @see FOFPlatformInterface::getDocument()
397 *
398 * @return JDocument
399 */
400 public function getDocument()
401 {
402 $document = null;
403
404 if (!$this->isCli())
405 {
406 try
407 {
408 $document = JFactory::getDocument();
409 }
410 catch (Exception $exc)
411 {
412 $document = null;
413 }
414 }
415
416 return $document;
417 }
418
419 /**
420 * Returns an object to handle dates
421 *
422 * @param mixed $time The initial time
423 * @param null $tzOffest The timezone offset
424 * @param bool $locale Should I try to load a specific class for current language?
425 *
426 * @return JDate object
427 */
428 public function getDate($time = 'now', $tzOffest = null, $locale = true)
429 {
430 if($locale)
431 {
432 return JFactory::getDate($time, $tzOffest);
433 }
434 else
435 {
436 return new JDate($time, $tzOffest);
437 }
438 }
439
440 public function getLanguage()
441 {
442 return JFactory::getLanguage();
443 }
444
445 public function getDbo()
446 {
447 return FOFDatabaseFactory::getInstance()->getDriver('joomla');
448 }
449
450 /**
451 * This method will try retrieving a variable from the request (input) data.
452 *
453 * @param string $key The user state key for the variable
454 * @param string $request The request variable name for the variable
455 * @param FOFInput $input The FOFInput object with the request (input) data
456 * @param mixed $default The default value. Default: null
457 * @param string $type The filter type for the variable data. Default: none (no filtering)
458 * @param boolean $setUserState Should I set the user state with the fetched value?
459 *
460 * @see FOFPlatformInterface::getUserStateFromRequest()
461 *
462 * @return mixed The value of the variable
463 */
464 public function getUserStateFromRequest($key, $request, $input, $default = null, $type = 'none', $setUserState = true)
465 {
466 list($isCLI, $isAdmin) = $this->isCliAdmin();
467
468 if ($isCLI)
469 {
470 return $input->get($request, $default, $type);
471 }
472
473 $app = JFactory::getApplication();
474
475 if (method_exists($app, 'getUserState'))
476 {
477 $old_state = $app->getUserState($key, $default);
478 }
479 else
480 {
481 $old_state = null;
482 }
483
484 $cur_state = (!is_null($old_state)) ? $old_state : $default;
485 $new_state = $input->get($request, null, $type);
486
487 // Save the new value only if it was set in this request
488 if ($setUserState)
489 {
490 if ($new_state !== null)
491 {
492 $app->setUserState($key, $new_state);
493 }
494 else
495 {
496 $new_state = $cur_state;
497 }
498 }
499 elseif (is_null($new_state))
500 {
501 $new_state = $cur_state;
502 }
503
504 return $new_state;
505 }
506
507 /**
508 * Load plugins of a specific type. Obviously this seems to only be required
509 * in the Joomla! CMS.
510 *
511 * @param string $type The type of the plugins to be loaded
512 *
513 * @see FOFPlatformInterface::importPlugin()
514 *
515 * @return void
516 */
517 public function importPlugin($type)
518 {
519 if (!$this->isCli())
520 {
521 JLoader::import('joomla.plugin.helper');
522 JPluginHelper::importPlugin($type);
523 }
524 }
525
526 /**
527 * Execute plugins (system-level triggers) and fetch back an array with
528 * their return values.
529 *
530 * @param string $event The event (trigger) name, e.g. onBeforeScratchMyEar
531 * @param array $data A hash array of data sent to the plugins as part of the trigger
532 *
533 * @see FOFPlatformInterface::runPlugins()
534 *
535 * @return array A simple array containing the results of the plugins triggered
536 */
537 public function runPlugins($event, $data)
538 {
539 if (!$this->isCli())
540 {
541 $app = JFactory::getApplication();
542
543 if (method_exists($app, 'triggerEvent'))
544 {
545 return $app->triggerEvent($event, $data);
546 }
547
548 // IMPORTANT: DO NOT REPLACE THIS INSTANCE OF JDispatcher WITH ANYTHING ELSE. WE NEED JOOMLA!'S PLUGIN EVENT
549 // DISPATCHER HERE, NOT OUR GENERIC EVENTS DISPATCHER
550 if (class_exists('JEventDispatcher'))
551 {
552 $dispatcher = JEventDispatcher::getInstance();
553 }
554 else
555 {
556 $dispatcher = JDispatcher::getInstance();
557 }
558
559 return $dispatcher->trigger($event, $data);
560 }
561 else
562 {
563 return array();
564 }
565 }
566
567 /**
568 * Perform an ACL check.
569 *
570 * @param string $action The ACL privilege to check, e.g. core.edit
571 * @param string $assetname The asset name to check, typically the component's name
572 *
573 * @see FOFPlatformInterface::authorise()
574 *
575 * @return boolean True if the user is allowed this action
576 */
577 public function authorise($action, $assetname)
578 {
579 if ($this->isCli())
580 {
581 return true;
582 }
583
584 return JFactory::getUser()->authorise($action, $assetname);
585 }
586
587 /**
588 * Is this the administrative section of the component?
589 *
590 * @see FOFPlatformInterface::isBackend()
591 *
592 * @return boolean
593 */
594 public function isBackend()
595 {
596 list ($isCli, $isAdmin) = $this->isCliAdmin();
597
598 return $isAdmin && !$isCli;
599 }
600
601 /**
602 * Is this the public section of the component?
603 *
604 * @see FOFPlatformInterface::isFrontend()
605 *
606 * @return boolean
607 */
608 public function isFrontend()
609 {
610 list ($isCli, $isAdmin) = $this->isCliAdmin();
611
612 return !$isAdmin && !$isCli;
613 }
614
615 /**
616 * Is this a component running in a CLI application?
617 *
618 * @see FOFPlatformInterface::isCli()
619 *
620 * @return boolean
621 */
622 public function isCli()
623 {
624 list ($isCli, $isAdmin) = $this->isCliAdmin();
625
626 return !$isAdmin && $isCli;
627 }
628
629 /**
630 * Is AJAX re-ordering supported? This is 100% Joomla!-CMS specific. All
631 * other platforms should return false and never ask why.
632 *
633 * @see FOFPlatformInterface::supportsAjaxOrdering()
634 *
635 * @return boolean
636 */
637 public function supportsAjaxOrdering()
638 {
639 return version_compare(JVERSION, '3.0', 'ge');
640 }
641
642 /**
643 * Is the global FOF cache enabled?
644 *
645 * @return boolean
646 */
647 public function isGlobalFOFCacheEnabled()
648 {
649 return !(defined('JDEBUG') && JDEBUG);
650 }
651
652 /**
653 * Saves something to the cache. This is supposed to be used for system-wide
654 * FOF data, not application data.
655 *
656 * @param string $key The key of the data to save
657 * @param string $content The actual data to save
658 *
659 * @return boolean True on success
660 */
661 public function setCache($key, $content)
662 {
663 $registry = $this->getCacheObject();
664
665 $registry->set($key, $content);
666
667 return $this->saveCache();
668 }
669
670 /**
671 * Retrieves data from the cache. This is supposed to be used for system-side
672 * FOF data, not application data.
673 *
674 * @param string $key The key of the data to retrieve
675 * @param string $default The default value to return if the key is not found or the cache is not populated
676 *
677 * @return string The cached value
678 */
679 public function getCache($key, $default = null)
680 {
681 $registry = $this->getCacheObject();
682
683 return $registry->get($key, $default);
684 }
685
686 /**
687 * Gets a reference to the cache object, loading it from the disk if
688 * needed.
689 *
690 * @param boolean $force Should I forcibly reload the registry?
691 *
692 * @return JRegistry
693 */
694 private function &getCacheObject($force = false)
695 {
696 // Check if we have to load the cache file or we are forced to do that
697 if (is_null($this->_cache) || $force)
698 {
699 // Create a new JRegistry object
700 JLoader::import('joomla.registry.registry');
701 $this->_cache = new JRegistry;
702
703 // Try to get data from Joomla!'s cache
704 $cache = JFactory::getCache('fof', '');
705 $data = $cache->get('cache', 'fof');
706
707 // If data is not found, fall back to the legacy (FOF 2.1.rc3 and earlier) method
708 if ($data === false)
709 {
710 // Find the path to the file
711 $cachePath = JPATH_CACHE . '/fof';
712 $filename = $cachePath . '/cache.php';
713 $filesystem = $this->getIntegrationObject('filesystem');
714
715 // Load the cache file if it exists. JRegistryFormatPHP fails
716 // miserably, so I have to work around it.
717 if ($filesystem->fileExists($filename))
718 {
719 @include_once $filename;
720
721 $filesystem->fileDelete($filename);
722
723 $className = 'FOFCacheStorage';
724
725 if (class_exists($className))
726 {
727 $object = new $className;
728 $this->_cache->loadObject($object);
729
730 $options = array(
731 'class' => 'FOFCacheStorage'
732 );
733 $cache->store($this->_cache, 'cache', 'fof');
734 }
735 }
736 }
737 else
738 {
739 $this->_cache = $data;
740 }
741 }
742
743 return $this->_cache;
744 }
745
746 /**
747 * Save the cache object back to disk
748 *
749 * @return boolean True on success
750 */
751 private function saveCache()
752 {
753 // Get the JRegistry object of our cached data
754 $registry = $this->getCacheObject();
755
756 $cache = JFactory::getCache('fof', '');
757 return $cache->store($registry, 'cache', 'fof');
758 }
759
760 /**
761 * Clears the cache of system-wide FOF data. You are supposed to call this in
762 * your components' installation script post-installation and post-upgrade
763 * methods or whenever you are modifying the structure of database tables
764 * accessed by FOF. Please note that FOF's cache never expires and is not
765 * purged by Joomla!. You MUST use this method to manually purge the cache.
766 *
767 * @return boolean True on success
768 */
769 public function clearCache()
770 {
771 $false = false;
772 $cache = JFactory::getCache('fof', '');
773 $cache->store($false, 'cache', 'fof');
774 }
775
776 public function getConfig()
777 {
778 return JFactory::getConfig();
779 }
780
781 /**
782 * logs in a user
783 *
784 * @param array $authInfo authentification information
785 *
786 * @return boolean True on success
787 */
788 public function loginUser($authInfo)
789 {
790 JLoader::import('joomla.user.authentication');
791 $options = array('remember' => false);
792 $authenticate = JAuthentication::getInstance();
793 $response = $authenticate->authenticate($authInfo, $options);
794
795 // User failed to authenticate: maybe he enabled two factor authentication?
796 // Let's try again "manually", skipping the check vs two factor auth
797 // Due the big mess with encryption algorithms and libraries, we are doing this extra check only
798 // if we're in Joomla 2.5.18+ or 3.2.1+
799 if($response->status != JAuthentication::STATUS_SUCCESS && method_exists('JUserHelper', 'verifyPassword'))
800 {
801 $db = $this->getDbo();
802 $query = $db->getQuery(true)
803 ->select('id, password')
804 ->from('#__users')
805 ->where('username=' . $db->quote($authInfo['username']));
806 $result = $db->setQuery($query)->loadObject();
807
808 if ($result)
809 {
810
811 $match = JUserHelper::verifyPassword($authInfo['password'], $result->password, $result->id);
812
813 if ($match === true)
814 {
815 // Bring this in line with the rest of the system
816 $user = JUser::getInstance($result->id);
817 $response->email = $user->email;
818 $response->fullname = $user->name;
819
820 if (JFactory::getApplication()->isAdmin())
821 {
822 $response->language = $user->getParam('admin_language');
823 }
824 else
825 {
826 $response->language = $user->getParam('language');
827 }
828
829 $response->status = JAuthentication::STATUS_SUCCESS;
830 $response->error_message = '';
831 }
832 }
833 }
834
835 if ($response->status == JAuthentication::STATUS_SUCCESS)
836 {
837 $this->importPlugin('user');
838 $results = $this->runPlugins('onLoginUser', array((array) $response, $options));
839
840 JLoader::import('joomla.user.helper');
841 $userid = JUserHelper::getUserId($response->username);
842 $user = $this->getUser($userid);
843
844 $session = JFactory::getSession();
845 $session->set('user', $user);
846
847 return true;
848 }
849
850 return false;
851 }
852
853 /**
854 * logs out a user
855 *
856 * @return boolean True on success
857 */
858 public function logoutUser()
859 {
860 JLoader::import('joomla.user.authentication');
861 $app = JFactory::getApplication();
862 $options = array('remember' => false);
863 $parameters = array('username' => $this->getUser()->username);
864
865 return $app->triggerEvent('onLogoutUser', array($parameters, $options));
866 }
867
868 public function logAddLogger($file)
869 {
870 if (!class_exists('JLog'))
871 {
872 return;
873 }
874
875 JLog::addLogger(array('text_file' => $file), JLog::ALL, array('fof'));
876 }
877
878 /**
879 * Logs a deprecated practice. In Joomla! this results in the $message being output in the
880 * deprecated log file, found in your site's log directory.
881 *
882 * @param string $message The deprecated practice log message
883 *
884 * @return void
885 */
886 public function logDeprecated($message)
887 {
888 if (!class_exists('JLog'))
889 {
890 return;
891 }
892
893 JLog::add($message, JLog::WARNING, 'deprecated');
894 }
895
896 public function logDebug($message)
897 {
898 if (!class_exists('JLog'))
899 {
900 return;
901 }
902
903 JLog::add($message, JLog::DEBUG, 'fof');
904 }
905
906 /**
907 * Returns the root URI for the request.
908 *
909 * @param boolean $pathonly If false, prepend the scheme, host and port information. Default is false.
910 * @param string $path The path
911 *
912 * @return string The root URI string.
913 */
914 public function URIroot($pathonly = false, $path = null)
915 {
916 JLoader::import('joomla.environment.uri');
917
918 return JUri::root($pathonly, $path);
919 }
920
921 /**
922 * Returns the base URI for the request.
923 *
924 * @param boolean $pathonly If false, prepend the scheme, host and port information. Default is false.
925 * |
926 * @return string The base URI string
927 */
928 public function URIbase($pathonly = false)
929 {
930 JLoader::import('joomla.environment.uri');
931
932 return JUri::base($pathonly);
933 }
934
935 /**
936 * Method to set a response header. If the replace flag is set then all headers
937 * with the given name will be replaced by the new one (only if the current platform supports header caching)
938 *
939 * @param string $name The name of the header to set.
940 * @param string $value The value of the header to set.
941 * @param boolean $replace True to replace any headers with the same name.
942 *
943 * @return void
944 */
945 public function setHeader($name, $value, $replace = false)
946 {
947 if (version_compare($this->version, '3.2', 'ge'))
948 {
949 JFactory::getApplication()->setHeader($name, $value, $replace);
950 }
951 else
952 {
953 JResponse::setHeader($name, $value, $replace);
954 }
955 }
956
957 public function sendHeaders()
958 {
959 if (version_compare($this->version, '3.2', 'ge'))
960 {
961 JFactory::getApplication()->sendHeaders();
962 }
963 else
964 {
965 JResponse::sendHeaders();
966 }
967 }
968 }
969