297 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			297 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * @package   FOF
 | |
|  * @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
 | |
|  * @license   GNU General Public License version 3, or later
 | |
|  */
 | |
| 
 | |
| namespace FOF40\View\DataView;
 | |
| 
 | |
| defined('_JEXEC') || die;
 | |
| 
 | |
| use FOF40\Model\DataModel;
 | |
| use Joomla\CMS\Document\Document as JoomlaDocument;
 | |
| use Joomla\CMS\Document\JsonDocument;
 | |
| use Joomla\CMS\Uri\Uri;
 | |
| 
 | |
| class Json extends Raw implements DataViewInterface
 | |
| {
 | |
| 	/**
 | |
| 	 * Set to true if your onBefore* methods have already populated the item, items, limitstart etc properties used to
 | |
| 	 * render a JSON document.
 | |
| 	 *
 | |
| 	 * @var bool
 | |
| 	 */
 | |
| 	public $alreadyLoaded = false;
 | |
| 
 | |
| 	/**
 | |
| 	 * Record listing offset (how many records to skip before starting showing some)
 | |
| 	 *
 | |
| 	 * @var   int
 | |
| 	 */
 | |
| 	protected $limitStart = 0;
 | |
| 
 | |
| 	/**
 | |
| 	 * Record listing limit (how many records to show)
 | |
| 	 *
 | |
| 	 * @var   int
 | |
| 	 */
 | |
| 	protected $limit = 10;
 | |
| 
 | |
| 	/**
 | |
| 	 * Total number of records in the result set
 | |
| 	 *
 | |
| 	 * @var   int
 | |
| 	 */
 | |
| 	protected $total = 0;
 | |
| 
 | |
| 	/**
 | |
| 	 * The record being displayed
 | |
| 	 *
 | |
| 	 * @var   DataModel
 | |
| 	 */
 | |
| 	protected $item;
 | |
| 
 | |
| 	/**
 | |
| 	 * Overrides the default method to execute and display a template script.
 | |
| 	 * Instead of loadTemplate is uses loadAnyTemplate.
 | |
| 	 *
 | |
| 	 * @param   string  $tpl  The name of the template file to parse
 | |
| 	 *
 | |
| 	 * @return  boolean  True on success
 | |
| 	 *
 | |
| 	 * @throws  \Exception  When the layout file is not found
 | |
| 	 */
 | |
| 	public function display($tpl = null)
 | |
| 	{
 | |
| 		$eventName = 'onBefore' . ucfirst($this->doTask);
 | |
| 		$this->triggerEvent($eventName, [$tpl]);
 | |
| 
 | |
| 		$eventName = 'onAfter' . ucfirst($this->doTask);
 | |
| 		$this->triggerEvent($eventName, [$tpl]);
 | |
| 
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * The event which runs when we are displaying the record list JSON view
 | |
| 	 *
 | |
| 	 * @param   string  $tpl  The sub-template to use
 | |
| 	 */
 | |
| 	public function onBeforeBrowse($tpl = null)
 | |
| 	{
 | |
| 		// Load the model
 | |
| 		/** @var DataModel $model */
 | |
| 		$model = $this->getModel();
 | |
| 
 | |
| 		$result = '';
 | |
| 
 | |
| 		if (!$this->alreadyLoaded)
 | |
| 		{
 | |
| 			$this->limitStart = $model->getState('limitstart', 0);
 | |
| 			$this->limit      = $model->getState('limit', 0);
 | |
| 			$this->items      = $model->get(true, $this->limitStart, $this->limit);
 | |
| 			$this->total      = $model->count();
 | |
| 		}
 | |
| 
 | |
| 		$document = $this->container->platform->getDocument();
 | |
| 
 | |
| 		/** @var JsonDocument $document */
 | |
| 		if ($document instanceof JoomlaDocument)
 | |
| 		{
 | |
| 			$document->setMimeEncoding('application/json');
 | |
| 		}
 | |
| 
 | |
| 		if (is_null($tpl))
 | |
| 		{
 | |
| 			$tpl = 'json';
 | |
| 		}
 | |
| 
 | |
| 		$hasFailed = false;
 | |
| 
 | |
| 		try
 | |
| 		{
 | |
| 			$result = $this->loadTemplate($tpl, true);
 | |
| 
 | |
| 			if ($result instanceof \Exception)
 | |
| 			{
 | |
| 				$hasFailed = true;
 | |
| 			}
 | |
| 		}
 | |
| 		catch (\Exception $e)
 | |
| 		{
 | |
| 			$hasFailed = true;
 | |
| 		}
 | |
| 
 | |
| 		if ($hasFailed)
 | |
| 		{
 | |
| 			// Default JSON behaviour in case the template isn't there!
 | |
| 			$result = [];
 | |
| 
 | |
| 			foreach ($this->items as $item)
 | |
| 			{
 | |
| 				$result[] = (is_object($item) && method_exists($item, 'toArray')) ? $item->toArray() : $item;
 | |
| 			}
 | |
| 
 | |
| 			$json = json_encode($result, JSON_PRETTY_PRINT);
 | |
| 
 | |
| 			// JSONP support
 | |
| 			$callback = $this->input->get('callback', null, 'raw');
 | |
| 
 | |
| 			if (!empty($callback))
 | |
| 			{
 | |
| 				echo $callback . '(' . $json . ')';
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				$defaultName = $this->input->get('view', 'main', 'cmd');
 | |
| 				$filename    = $this->input->get('basename', $defaultName, 'cmd');
 | |
| 
 | |
| 				$document->setName($filename);
 | |
| 				echo $json;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			echo $result;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * The event which runs when we are displaying a single item JSON view
 | |
| 	 *
 | |
| 	 * @param   string  $tpl  The view sub-template to use
 | |
| 	 */
 | |
| 	protected function onBeforeRead($tpl = null)
 | |
| 	{
 | |
| 		self::renderSingleItem($tpl);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * The event which runs when we are displaying a single item JSON view
 | |
| 	 *
 | |
| 	 * @param   string  $tpl  The view sub-template to use
 | |
| 	 */
 | |
| 	protected function onAfterSave($tpl = null)
 | |
| 	{
 | |
| 		self::renderSingleItem($tpl);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Renders a single item JSON view
 | |
| 	 *
 | |
| 	 * @param   string  $tpl  The view sub-template to use
 | |
| 	 */
 | |
| 	protected function renderSingleItem($tpl)
 | |
| 	{
 | |
| 		// Load the model
 | |
| 		/** @var DataModel $model */
 | |
| 		$model = $this->getModel();
 | |
| 
 | |
| 		$result = '';
 | |
| 
 | |
| 		if (!$this->alreadyLoaded)
 | |
| 		{
 | |
| 			$this->item = $model->find();
 | |
| 		}
 | |
| 
 | |
| 
 | |
| 		$document = $this->container->platform->getDocument();
 | |
| 
 | |
| 		/** @var JsonDocument $document */
 | |
| 		if ($document instanceof JoomlaDocument)
 | |
| 		{
 | |
| 			$document->setMimeEncoding('application/json');
 | |
| 		}
 | |
| 
 | |
| 		if (is_null($tpl))
 | |
| 		{
 | |
| 			$tpl = 'json';
 | |
| 		}
 | |
| 
 | |
| 		$hasFailed = false;
 | |
| 
 | |
| 		try
 | |
| 		{
 | |
| 			$result = $this->loadTemplate($tpl, true);
 | |
| 
 | |
| 			if ($result instanceof \Exception)
 | |
| 			{
 | |
| 				$hasFailed = true;
 | |
| 			}
 | |
| 		}
 | |
| 		catch (\Exception $e)
 | |
| 		{
 | |
| 			$hasFailed = true;
 | |
| 		}
 | |
| 
 | |
| 		if ($hasFailed)
 | |
| 		{
 | |
| 			$data = (is_object($this->item) && method_exists($this->item, 'toArray')) ? $this->item->toArray() : $this->item;
 | |
| 
 | |
| 			$json = json_encode($data, JSON_PRETTY_PRINT);
 | |
| 
 | |
| 			// JSONP support
 | |
| 			$callback = $this->input->get('callback');
 | |
| 
 | |
| 			if (!empty($callback))
 | |
| 			{
 | |
| 				echo $callback . '(' . $json . ')';
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				$defaultName = $this->input->get('view', 'main', 'cmd');
 | |
| 				$filename    = $this->input->get('basename', $defaultName, 'cmd');
 | |
| 				$document->setName($filename);
 | |
| 
 | |
| 				echo $json;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			echo $result;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Convert an absolute URI to a relative one
 | |
| 	 *
 | |
| 	 * @param   string  $uri  The URI to convert
 | |
| 	 *
 | |
| 	 * @return  string  The relative URL
 | |
| 	 */
 | |
| 	protected function _removeURIBase($uri)
 | |
| 	{
 | |
| 		static $root = null, $rootlen = 0;
 | |
| 
 | |
| 		if (is_null($root))
 | |
| 		{
 | |
| 			$root    = rtrim(Uri::base(false), '/');
 | |
| 			$rootlen = strlen($root);
 | |
| 		}
 | |
| 
 | |
| 		if (substr($uri, 0, $rootlen) == $root)
 | |
| 		{
 | |
| 			$uri = substr($uri, $rootlen);
 | |
| 		}
 | |
| 
 | |
| 		return ltrim($uri, '/');
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Returns a Uri instance with a prototype URI used as the base for the
 | |
| 	 * other URIs created by the JSON renderer
 | |
| 	 *
 | |
| 	 * @return  Uri  The prototype Uri instance
 | |
| 	 */
 | |
| 	protected function _getPrototypeURIForPagination()
 | |
| 	{
 | |
| 		$protoUri = new Uri('index.php');
 | |
| 		$protoUri->setQuery($this->input->getData());
 | |
| 		$protoUri->delVar('savestate');
 | |
| 		$protoUri->delVar('base_path');
 | |
| 
 | |
| 		return $protoUri;
 | |
| 	}
 | |
| }
 |