cms/components/com_ajax/ajax.php

278 lines
6.3 KiB
PHP

<?php
/**
* @package Joomla.Site
* @subpackage com_ajax
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Response\JsonResponse;
use Joomla\CMS\Table\Table;
/*
* References
* Support plugins in your component
* - https://docs.joomla.org/Special:MyLanguage/Supporting_plugins_in_your_component
*
* Best way for JSON output
* - https://groups.google.com/d/msg/joomla-dev-cms/WsC0nA9Fixo/Ur-gPqpqh-EJ
*/
/** @var \Joomla\CMS\Application\CMSApplication $app */
$app = Factory::getApplication();
$app->allowCache(false);
// JInput object
$input = $app->input;
// Requested format passed via URL
$format = strtolower($input->getWord('format'));
// Initialize default response and module name
$results = null;
$parts = null;
// Check for valid format
if (!$format)
{
$results = new InvalidArgumentException(Text::_('COM_AJAX_SPECIFY_FORMAT'), 404);
}
/*
* Module support.
*
* modFooHelper::getAjax() is called where 'foo' is the value
* of the 'module' variable passed via the URL
* (i.e. index.php?option=com_ajax&module=foo).
*
*/
elseif ($input->get('module'))
{
$module = $input->get('module');
$table = Table::getInstance('extension');
$moduleId = $table->find(array('type' => 'module', 'element' => 'mod_' . $module));
if ($moduleId && $table->load($moduleId) && $table->enabled)
{
$helperFile = JPATH_BASE . '/modules/mod_' . $module . '/helper.php';
if (strpos($module, '_'))
{
$parts = explode('_', $module);
}
elseif (strpos($module, '-'))
{
$parts = explode('-', $module);
}
if ($parts)
{
$class = 'Mod';
foreach ($parts as $part)
{
$class .= ucfirst($part);
}
$class .= 'Helper';
}
else
{
$class = 'Mod' . ucfirst($module) . 'Helper';
}
$method = $input->get('method') ?: 'get';
if (is_file($helperFile))
{
JLoader::register($class, $helperFile);
if (method_exists($class, $method . 'Ajax'))
{
// Load language file for module
$basePath = JPATH_BASE;
$lang = Factory::getLanguage();
$lang->load('mod_' . $module, $basePath)
|| $lang->load('mod_' . $module, $basePath . '/modules/mod_' . $module);
try
{
$results = call_user_func($class . '::' . $method . 'Ajax');
}
catch (Exception $e)
{
$results = $e;
}
}
// Method does not exist
else
{
$results = new LogicException(Text::sprintf('COM_AJAX_METHOD_NOT_EXISTS', $method . 'Ajax'), 404);
}
}
// The helper file does not exist
else
{
$results = new RuntimeException(Text::sprintf('COM_AJAX_FILE_NOT_EXISTS', 'mod_' . $module . '/helper.php'), 404);
}
}
// Module is not published, you do not have access to it, or it is not assigned to the current menu item
else
{
$results = new LogicException(Text::sprintf('COM_AJAX_MODULE_NOT_ACCESSIBLE', 'mod_' . $module), 404);
}
}
/*
* Plugin support by default is based on the "Ajax" plugin group.
* An optional 'group' variable can be passed via the URL.
*
* The plugin event triggered is onAjaxFoo, where 'foo' is
* the value of the 'plugin' variable passed via the URL
* (i.e. index.php?option=com_ajax&plugin=foo)
*
*/
elseif ($input->get('plugin'))
{
$group = $input->get('group', 'ajax');
PluginHelper::importPlugin($group);
$plugin = ucfirst($input->get('plugin'));
try
{
$results = Factory::getApplication()->triggerEvent('onAjax' . $plugin);
}
catch (Exception $e)
{
$results = $e;
}
}
/*
* Template support.
*
* tplFooHelper::getAjax() is called where 'foo' is the value
* of the 'template' variable passed via the URL
* (i.e. index.php?option=com_ajax&template=foo).
*
*/
elseif ($input->get('template'))
{
$template = $input->get('template');
$table = Table::getInstance('extension');
$templateId = $table->find(array('type' => 'template', 'element' => $template));
if ($templateId && $table->load($templateId) && $table->enabled)
{
$basePath = ($table->client_id) ? JPATH_ADMINISTRATOR : JPATH_SITE;
$helperFile = $basePath . '/templates/' . $template . '/helper.php';
if (strpos($template, '_'))
{
$parts = explode('_', $template);
}
elseif (strpos($template, '-'))
{
$parts = explode('-', $template);
}
if ($parts)
{
$class = 'Tpl';
foreach ($parts as $part)
{
$class .= ucfirst($part);
}
$class .= 'Helper';
}
else
{
$class = 'Tpl' . ucfirst($template) . 'Helper';
}
$method = $input->get('method') ?: 'get';
if (is_file($helperFile))
{
JLoader::register($class, $helperFile);
if (method_exists($class, $method . 'Ajax'))
{
// Load language file for template
$lang = Factory::getLanguage();
$lang->load('tpl_' . $template, $basePath)
|| $lang->load('tpl_' . $template, $basePath . '/templates/' . $template);
try
{
$results = call_user_func($class . '::' . $method . 'Ajax');
}
catch (Exception $e)
{
$results = $e;
}
}
// Method does not exist
else
{
$results = new LogicException(Text::sprintf('COM_AJAX_METHOD_NOT_EXISTS', $method . 'Ajax'), 404);
}
}
// The helper file does not exist
else
{
$results = new RuntimeException(Text::sprintf('COM_AJAX_FILE_NOT_EXISTS', 'tpl_' . $template . '/helper.php'), 404);
}
}
// Template is not assigned to the current menu item
else
{
$results = new LogicException(Text::sprintf('COM_AJAX_TEMPLATE_NOT_ACCESSIBLE', 'tpl_' . $template), 404);
}
}
// Return the results in the desired format
switch ($format)
{
// JSONinzed
case 'json' :
echo new JsonResponse($results, null, false, $input->get('ignoreMessages', true, 'bool'));
break;
// Handle as raw format
default :
// Output exception
if ($results instanceof Exception)
{
// Log an error
Log::add($results->getMessage(), Log::ERROR);
// Set status header code
$app->setHeader('status', $results->getCode(), true);
// Echo exception type and message
$out = get_class($results) . ': ' . $results->getMessage();
}
// Output string/ null
elseif (is_scalar($results))
{
$out = (string) $results;
}
// Output array/ object
else
{
$out = implode((array) $results);
}
echo $out;
break;
}