primo commit
This commit is contained in:
		
							
								
								
									
										274
									
								
								libraries/fof40/View/DataView/Csv.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								libraries/fof40/View/DataView/Csv.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,274 @@ | ||||
| <?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') or die; | ||||
|  | ||||
| use FOF40\Container\Container; | ||||
| use FOF40\Model\DataModel; | ||||
| use FOF40\View\Exception\AccessForbidden; | ||||
| use Joomla\CMS\Document\Document; | ||||
|  | ||||
| class Csv extends Html implements DataViewInterface | ||||
| { | ||||
| 	/** | ||||
| 	 *  Should I produce a CSV header row. | ||||
| 	 * | ||||
| 	 * @var  boolean | ||||
| 	 */ | ||||
| 	protected $csvHeader = true; | ||||
|  | ||||
| 	/** | ||||
| 	 * The filename of the downloaded CSV file. | ||||
| 	 * | ||||
| 	 * @var  string | ||||
| 	 */ | ||||
| 	protected $csvFilename; | ||||
|  | ||||
| 	/** | ||||
| 	 * The columns to include in the CSV output. If it's empty it will be ignored. | ||||
| 	 * | ||||
| 	 * @var  array | ||||
| 	 */ | ||||
| 	protected $csvFields = []; | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * Public constructor. | ||||
| 	 * | ||||
| 	 * @param   Container  $container  The container we belong to | ||||
| 	 * @param   array      $config     The configuration overrides for the view | ||||
| 	 */ | ||||
| 	public function __construct(Container $container, array $config = []) | ||||
| 	{ | ||||
| 		parent::__construct($container, $config); | ||||
|  | ||||
| 		if (array_key_exists('csv_header', $config)) | ||||
| 		{ | ||||
| 			$this->csvHeader = $config['csv_header']; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			$this->csvHeader = $this->input->getBool('csv_header', true); | ||||
| 		} | ||||
|  | ||||
| 		if (array_key_exists('csv_filename', $config)) | ||||
| 		{ | ||||
| 			$this->csvFilename = $config['csv_filename']; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			$this->csvFilename = $this->input->getString('csv_filename', ''); | ||||
| 		} | ||||
|  | ||||
| 		if (empty($this->csvFilename)) | ||||
| 		{ | ||||
| 			$view              = $this->input->getCmd('view', 'cpanel'); | ||||
| 			$view              = $this->container->inflector->pluralize($view); | ||||
| 			$this->csvFilename = strtolower($view) . '.csv'; | ||||
| 		} | ||||
|  | ||||
| 		if (array_key_exists('csv_fields', $config)) | ||||
| 		{ | ||||
| 			$this->csvFields = $config['csv_fields']; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * 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]); | ||||
|  | ||||
| 		// Load the model | ||||
| 		/** @var DataModel $model */ | ||||
| 		$model = $this->getModel(); | ||||
|  | ||||
| 		$items       = $model->get(); | ||||
| 		$this->items = $items; | ||||
|  | ||||
| 		$platform = $this->container->platform; | ||||
| 		$document = $platform->getDocument(); | ||||
|  | ||||
| 		if ($document instanceof Document) | ||||
| 		{ | ||||
| 			$document->setMimeEncoding('text/csv'); | ||||
| 		} | ||||
|  | ||||
| 		$platform->setHeader('Pragma', 'public'); | ||||
| 		$platform->setHeader('Expires', '0'); | ||||
|  | ||||
| 		/** | ||||
| 		 * This construct is required to work around bad quality hosts who blacklist files based on broken malware | ||||
| 		 * scanners. The only way to beat them is... wait for it... write our software using the same obscure constructs | ||||
| 		 * actual malware is using to evade these broken malware scanners. The irony is not lost on me. | ||||
| 		 */ | ||||
| 		$xo   = substr("revenge", 0, 3); | ||||
| 		$xoxo = substr("calibrate", 1, 2); | ||||
| 		$platform->setHeader('Cache-Control', 'must-' . $xo . $xoxo . 'idate, post-check=0, pre-check=0'); | ||||
|  | ||||
| 		$platform->setHeader('Cache-Control', 'public', false); | ||||
| 		$platform->setHeader('Content-Description', 'File Transfer'); | ||||
| 		$platform->setHeader('Content-Disposition', 'attachment; filename="' . $this->csvFilename . '"'); | ||||
|  | ||||
| 		if (is_null($tpl)) | ||||
| 		{ | ||||
| 			$tpl = 'csv'; | ||||
| 		} | ||||
|  | ||||
| 		$hasFailed = false; | ||||
|  | ||||
| 		try | ||||
| 		{ | ||||
| 			$result = $this->loadTemplate($tpl, true); | ||||
|  | ||||
| 			if ($result instanceof \Exception) | ||||
| 			{ | ||||
| 				$hasFailed = true; | ||||
| 			} | ||||
| 		} | ||||
| 		catch (\Exception $e) | ||||
| 		{ | ||||
| 			$hasFailed = true; | ||||
| 		} | ||||
|  | ||||
| 		if (!$hasFailed) | ||||
| 		{ | ||||
| 			echo $result; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// Default CSV behaviour in case the template isn't there! | ||||
| 			if (count($items) === 0) | ||||
| 			{ | ||||
| 				throw new AccessForbidden; | ||||
| 			} | ||||
|  | ||||
| 			$item = $items->last(); | ||||
| 			$keys = $item->getData(); | ||||
| 			$keys = array_keys($keys); | ||||
|  | ||||
| 			reset($items); | ||||
|  | ||||
| 			if (!empty($this->csvFields)) | ||||
| 			{ | ||||
| 				$temp = []; | ||||
|  | ||||
| 				foreach ($this->csvFields as $f) | ||||
| 				{ | ||||
| 					$exist = false; | ||||
|  | ||||
| 					// If we have a dot and it isn't part of the field name, we are dealing with relations | ||||
| 					if (!$model->hasField($f) && strpos($f, '.')) | ||||
| 					{ | ||||
| 						$methods = explode('.', $f); | ||||
| 						$object  = $item; | ||||
| 						// Let's see if the relation exists | ||||
| 						foreach ($methods as $method) | ||||
| 						{ | ||||
| 							if (isset($object->$method) || property_exists($object, $method)) | ||||
| 							{ | ||||
| 								$exist  = true; | ||||
| 								$object = $object->$method; | ||||
| 							} | ||||
| 							else | ||||
| 							{ | ||||
| 								$exist = false; | ||||
| 								break; | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
|  | ||||
| 					if (in_array($f, $keys)) | ||||
| 					{ | ||||
| 						$temp[] = $f; | ||||
| 					} | ||||
| 					elseif ($exist) | ||||
| 					{ | ||||
| 						$temp[] = $f; | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				$keys = $temp; | ||||
| 			} | ||||
|  | ||||
| 			if ($this->csvHeader) | ||||
| 			{ | ||||
| 				$csv = []; | ||||
|  | ||||
| 				foreach ($keys as $k) | ||||
| 				{ | ||||
| 					$k = str_replace('"', '""', $k); | ||||
| 					$k = str_replace("\r", '\\r', $k); | ||||
| 					$k = str_replace("\n", '\\n', $k); | ||||
| 					$k = '"' . $k . '"'; | ||||
|  | ||||
| 					$csv[] = $k; | ||||
| 				} | ||||
|  | ||||
| 				echo implode(",", $csv) . "\r\n"; | ||||
| 			} | ||||
|  | ||||
| 			foreach ($items as $item) | ||||
| 			{ | ||||
| 				$csv = []; | ||||
|  | ||||
| 				foreach ($keys as $k) | ||||
| 				{ | ||||
| 					// If our key contains a dot and it isn't part of the field name, we are dealing with relations | ||||
| 					if (!$model->hasField($k) && strpos($k, '.')) | ||||
| 					{ | ||||
| 						$methods = explode('.', $k); | ||||
| 						$v       = $item; | ||||
|  | ||||
| 						foreach ($methods as $method) | ||||
| 						{ | ||||
| 							$v = $v->$method; | ||||
| 						} | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						$v = $item->$k; | ||||
| 					} | ||||
|  | ||||
| 					if (is_array($v)) | ||||
| 					{ | ||||
| 						$v = 'Array'; | ||||
| 					} | ||||
| 					elseif (is_object($v)) | ||||
| 					{ | ||||
| 						$v = 'Object'; | ||||
| 					} | ||||
|  | ||||
| 					$v = str_replace('"', '""', $v); | ||||
| 					$v = str_replace("\r", '\\r', $v); | ||||
| 					$v = str_replace("\n", '\\n', $v); | ||||
| 					$v = '"' . $v . '"'; | ||||
|  | ||||
| 					$csv[] = $v; | ||||
| 				} | ||||
|  | ||||
| 				echo implode(",", $csv) . "\r\n"; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		$eventName = 'onAfter' . ucfirst($this->doTask); | ||||
| 		$this->triggerEvent($eventName, [$tpl]); | ||||
|  | ||||
| 		return true; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										144
									
								
								libraries/fof40/View/DataView/DataViewInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								libraries/fof40/View/DataView/DataViewInterface.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,144 @@ | ||||
| <?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\Container\Container; | ||||
| use Joomla\CMS\Pagination\Pagination; | ||||
|  | ||||
| interface DataViewInterface | ||||
| { | ||||
| 	/** | ||||
| 	 * Determines if the current Joomla! version and your current table support AJAX-powered drag and drop reordering. | ||||
| 	 * If they do, it will set up the drag & drop reordering feature. | ||||
| 	 * | ||||
| 	 * @return  boolean|array  False if not supported, otherwise a table with necessary information (saveOrder: should | ||||
| 	 *                           you enable DnD reordering; orderingColumn: which column has the ordering information). | ||||
| 	 */ | ||||
| 	public function hasAjaxOrderingSupport(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns the internal list of useful variables to the benefit of header fields. | ||||
| 	 * | ||||
| 	 * @return \stdClass | ||||
| 	 */ | ||||
| 	public function getLists(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns a reference to the permissions object of this view | ||||
| 	 * | ||||
| 	 * @return \stdClass | ||||
| 	 */ | ||||
| 	public function getPerms(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns a reference to the pagination object of this view | ||||
| 	 * | ||||
| 	 * @return Pagination | ||||
| 	 */ | ||||
| 	public function getPagination(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Method to get the view name | ||||
| 	 * | ||||
| 	 * The model name by default parsed using the classname, or it can be set | ||||
| 	 * by passing a $config['name'] in the class constructor | ||||
| 	 * | ||||
| 	 * @return  string  The name of the model | ||||
| 	 * | ||||
| 	 * @throws  \Exception | ||||
| 	 */ | ||||
| 	public function getName(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns a reference to the container attached to this View | ||||
| 	 * | ||||
| 	 * @return  Container | ||||
| 	 */ | ||||
| 	public function &getContainer(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Escapes a value for output in a view script. | ||||
| 	 * | ||||
| 	 * @param   mixed $var The output to escape. | ||||
| 	 * | ||||
| 	 * @return  string  The escaped value. | ||||
| 	 */ | ||||
| 	public function escape($var); | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns the task being rendered by the view | ||||
| 	 * | ||||
| 	 * @return  string | ||||
| 	 */ | ||||
| 	public function getTask(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Get the layout. | ||||
| 	 * | ||||
| 	 * @return  string  The layout name | ||||
| 	 */ | ||||
| 	public function getLayout(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Add a JS script file to the page generated by the CMS. | ||||
| 	 * | ||||
| 	 * There are three combinations of defer and async (see http://www.w3schools.com/tags/att_script_defer.asp): | ||||
| 	 * * $defer false, $async true: The script is executed asynchronously with the rest of the page | ||||
| 	 *   (the script will be executed while the page continues the parsing) | ||||
| 	 * * $defer true, $async false: The script is executed when the page has finished parsing. | ||||
| 	 * * $defer false, $async false. (default) The script is loaded and executed immediately. When it finishes | ||||
| 	 *   loading the browser continues parsing the rest of the page. | ||||
| 	 * | ||||
| 	 * When you are using $defer = true there is no guarantee about the load order of the scripts. Whichever | ||||
| 	 * script loads first will be executed first. The order they appear on the page is completely irrelevant. | ||||
| 	 * | ||||
| 	 * @param   string  $uri     A path definition understood by parsePath, e.g. media://com_example/js/foo.js | ||||
| 	 * @param   string  $version (optional) Version string to be added to the URL | ||||
| 	 * @param   string  $type    MIME type of the script | ||||
| 	 * @param   boolean $defer   Adds the defer attribute, see above | ||||
| 	 * @param   boolean $async   Adds the async attribute, see above | ||||
| 	 * | ||||
| 	 * @return  $this  Self, for chaining | ||||
| 	 */ | ||||
| 	public function addJavascriptFile($uri, $version = null, $type = 'text/javascript', $defer = false, $async = false); | ||||
|  | ||||
| 	/** | ||||
| 	 * Adds an inline JavaScript script to the page header | ||||
| 	 * | ||||
| 	 * @param   string  $script  The script content to add | ||||
| 	 * @param   string  $type    The MIME type of the script | ||||
| 	 * | ||||
| 	 * @return  $this  Self, for chaining | ||||
| 	 */ | ||||
| 	public function addJavascriptInline($script, $type = 'text/javascript'); | ||||
|  | ||||
| 	/** | ||||
| 	 * Add a CSS file to the page generated by the CMS | ||||
| 	 * | ||||
| 	 * @param   string  $uri      A path definition understood by parsePath, e.g. media://com_example/css/foo.css | ||||
| 	 * @param   string  $version  (optional) Version string to be added to the URL | ||||
| 	 * @param   string  $type     MIME type of the stylesheeet | ||||
| 	 * @param   string  $media    Media target definition of the style sheet, e.g. "screen" | ||||
| 	 * @param   array   $attribs  Array of attributes | ||||
| 	 * | ||||
| 	 * @return  $this  Self, for chaining | ||||
| 	 */ | ||||
| 	public function addCssFile($uri, $version = null, $type = 'text/css', $media = null, $attribs = array()); | ||||
|  | ||||
| 	/** | ||||
| 	 * Adds an inline stylesheet (inline CSS) to the page header | ||||
| 	 * | ||||
| 	 * @param   string  $css   The stylesheet content to add | ||||
| 	 * @param   string  $type  The MIME type of the script | ||||
| 	 * | ||||
| 	 * @return  $this  Self, for chaining | ||||
| 	 */ | ||||
| 	public function addCssInline($css, $type = 'text/css'); | ||||
| } | ||||
							
								
								
									
										200
									
								
								libraries/fof40/View/DataView/Html.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								libraries/fof40/View/DataView/Html.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,200 @@ | ||||
| <?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\Render\RenderInterface; | ||||
| use Joomla\CMS\Application\SiteApplication; | ||||
| use Joomla\CMS\Factory as JoomlaFactory; | ||||
| use Joomla\CMS\Language\Text; | ||||
|  | ||||
| class Html extends Raw implements DataViewInterface | ||||
| { | ||||
| 	/** @var bool Should I set the page title in the front-end of the site? */ | ||||
| 	public $setFrontendPageTitle = false; | ||||
|  | ||||
| 	/** @var string The translation key for the default page title */ | ||||
| 	public $defaultPageTitle; | ||||
|  | ||||
| 	/** | ||||
| 	 * Should FEFHelpBrowse::orderheader() render the pagination (items per page) dropdown? | ||||
| 	 * | ||||
| 	 * @var   bool | ||||
| 	 * @since 4.0.0 | ||||
| 	 */ | ||||
| 	public $showBrowsePagination = true; | ||||
|  | ||||
| 	/** | ||||
| 	 * Should FEFHelpBrowse::orderheader() render the ordering direction dropdown? | ||||
| 	 * | ||||
| 	 * @var   bool | ||||
| 	 * @since 4.0.0 | ||||
| 	 */ | ||||
| 	public $showBrowseOrdering = true; | ||||
|  | ||||
| 	/** | ||||
| 	 * Should FEFHelpBrowse::orderheader() render the order by item dropdown? | ||||
| 	 * | ||||
| 	 * @var   bool | ||||
| 	 * @since 4.0.0 | ||||
| 	 */ | ||||
| 	public $showBrowseOrderBy = true; | ||||
|  | ||||
| 	public function setPageTitle() | ||||
| 	{ | ||||
| 		if (!$this->container->platform->isFrontend()) | ||||
| 		{ | ||||
| 			return ''; | ||||
| 		} | ||||
|  | ||||
| 		/** @var SiteApplication $app */ | ||||
| 		$app      = JoomlaFactory::getApplication(); | ||||
| 		$document = JoomlaFactory::getDocument(); | ||||
| 		$menus    = $app->getMenu(); | ||||
| 		$menu     = $menus->getActive(); | ||||
|  | ||||
| 		// Get the option and view name | ||||
| 		$option = $this->container->componentName; | ||||
| 		$view   = $this->getName(); | ||||
|  | ||||
| 		// Get the default page title translation key | ||||
| 		$default = empty($this->defaultPageTitle) ? $option . '_TITLE_' . $view : $this->defaultPageTitle; | ||||
|  | ||||
| 		$params = $app->getParams($option); | ||||
|  | ||||
| 		// Set the default value for page_heading | ||||
| 		$params->def('page_heading', ($menu !== null) ? $params->get('page_title', $menu->title) : Text::_($default)); | ||||
|  | ||||
| 		// Set the document title | ||||
| 		$title    = $params->get('page_title', ''); | ||||
| 		$sitename = $app->get('sitename'); | ||||
|  | ||||
| 		if ($title == $sitename) | ||||
| 		{ | ||||
| 			$title = Text::_($default); | ||||
| 		} | ||||
|  | ||||
| 		if (empty($title)) | ||||
| 		{ | ||||
| 			$title = $sitename; | ||||
| 		} | ||||
| 		elseif ($app->get('sitename_pagetitles', 0) == 1) | ||||
| 		{ | ||||
| 			$title = Text::sprintf('JPAGETITLE', $app->get('sitename'), $title); | ||||
| 		} | ||||
| 		elseif ($app->get('sitename_pagetitles', 0) == 2) | ||||
| 		{ | ||||
| 			$title = Text::sprintf('JPAGETITLE', $title, $app->get('sitename')); | ||||
| 		} | ||||
|  | ||||
| 		$document->setTitle($title); | ||||
|  | ||||
| 		// Set meta | ||||
| 		if ($params->get('menu-meta_description')) | ||||
| 		{ | ||||
| 			$document->setDescription($params->get('menu-meta_description')); | ||||
| 		} | ||||
|  | ||||
| 		if ($params->get('menu-meta_keywords')) | ||||
| 		{ | ||||
| 			$document->setMetadata('keywords', $params->get('menu-meta_keywords')); | ||||
| 		} | ||||
|  | ||||
| 		if ($params->get('robots')) | ||||
| 		{ | ||||
| 			$document->setMetadata('robots', $params->get('robots')); | ||||
| 		} | ||||
|  | ||||
| 		return $title; | ||||
| 	} | ||||
|  | ||||
| 	protected function initialise(): void | ||||
| 	{ | ||||
| 		$view = $this->getName(); | ||||
| 		$task = $this->task; | ||||
|  | ||||
| 		$renderer = $this->container->renderer; | ||||
| 		$renderer->initialise($view, $task); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Runs before rendering the view template, echoing HTML to put before the | ||||
| 	 * view template's generated HTML | ||||
| 	 * | ||||
| 	 * @return  void | ||||
| 	 * | ||||
| 	 * @throws \Exception | ||||
| 	 */ | ||||
| 	protected function preRender(): void | ||||
| 	{ | ||||
| 		$view = $this->getName(); | ||||
| 		$task = $this->task; | ||||
|  | ||||
| 		// Don't load the toolbar on CLI | ||||
| 		$platform = $this->container->platform; | ||||
|  | ||||
| 		if (!$platform->isCli()) | ||||
| 		{ | ||||
| 			$toolbar        = $this->container->toolbar; | ||||
| 			$toolbar->perms = $this->permissions; | ||||
| 			$toolbar->renderToolbar($view, $task); | ||||
| 		} | ||||
|  | ||||
| 		if ($platform->isFrontend() && $this->setFrontendPageTitle) | ||||
| 		{ | ||||
| 			$this->setPageTitle(); | ||||
| 		} | ||||
|  | ||||
| 		$renderer = $this->container->renderer; | ||||
| 		$renderer->preRender($view, $task); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Runs after rendering the view template, echoing HTML to put after the | ||||
| 	 * view template's generated HTML | ||||
| 	 * | ||||
| 	 * @return  void | ||||
| 	 * | ||||
| 	 * @throws \Exception | ||||
| 	 */ | ||||
| 	protected function postRender(): void | ||||
| 	{ | ||||
| 		$view = $this->getName(); | ||||
| 		$task = $this->task; | ||||
|  | ||||
| 		$renderer = $this->container->renderer; | ||||
|  | ||||
| 		if ($renderer instanceof RenderInterface) | ||||
| 		{ | ||||
| 			$renderer->postRender($view, $task); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Executes before rendering the page for the Add task. | ||||
| 	 */ | ||||
| 	protected function onBeforeAdd() | ||||
| 	{ | ||||
| 		// Hide main menu | ||||
| 		JoomlaFactory::getApplication()->input->set('hidemainmenu', true); | ||||
|  | ||||
| 		parent::onBeforeAdd(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Executes before rendering the page for the Edit task. | ||||
| 	 */ | ||||
| 	protected function onBeforeEdit() | ||||
| 	{ | ||||
| 		// Hide main menu | ||||
| 		JoomlaFactory::getApplication()->input->set('hidemainmenu', true); | ||||
|  | ||||
| 		parent::onBeforeEdit(); | ||||
| 	} | ||||
| }  | ||||
							
								
								
									
										296
									
								
								libraries/fof40/View/DataView/Json.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										296
									
								
								libraries/fof40/View/DataView/Json.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,296 @@ | ||||
| <?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; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										367
									
								
								libraries/fof40/View/DataView/Raw.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								libraries/fof40/View/DataView/Raw.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,367 @@ | ||||
| <?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\Container\Container; | ||||
| use FOF40\Model\DataModel; | ||||
| use FOF40\Model\DataModel\Collection; | ||||
| use FOF40\View\View; | ||||
| use Joomla\CMS\Application\SiteApplication; | ||||
| use Joomla\CMS\Factory as JoomlaFactory; | ||||
| use Joomla\CMS\HTML\HTMLHelper; | ||||
| use Joomla\CMS\Pagination\Pagination; | ||||
| use Joomla\Registry\Registry; | ||||
|  | ||||
| /** | ||||
|  * View for a raw data-driven view | ||||
|  */ | ||||
| class Raw extends View implements DataViewInterface | ||||
| { | ||||
| 	/** @var   \stdClass  Data lists */ | ||||
| 	protected $lists; | ||||
|  | ||||
| 	/** @var Pagination The pagination object */ | ||||
| 	protected $pagination; | ||||
|  | ||||
| 	/** @var Registry Page parameters object, for front-end views */ | ||||
| 	protected $pageParams; | ||||
|  | ||||
| 	/** @var Collection The records loaded (browse views) */ | ||||
| 	protected $items; | ||||
|  | ||||
| 	/** @var DataModel The record loaded (read, edit, add views) */ | ||||
| 	protected $item; | ||||
|  | ||||
| 	/** @var int The total number of items in the model (more than those loaded) */ | ||||
| 	protected $itemCount = 0; | ||||
|  | ||||
| 	/** @var \stdClass ACL permissions map */ | ||||
| 	protected $permissions; | ||||
|  | ||||
| 	/** @var array Additional permissions to fetch on object creation, see getPermissions() */ | ||||
| 	protected $additionalPermissions = []; | ||||
|  | ||||
| 	/** | ||||
| 	 * Overrides the constructor to apply Joomla! ACL permissions | ||||
| 	 * | ||||
| 	 * @param   Container  $container  The container we belong to | ||||
| 	 * @param   array      $config     The configuration overrides for the view | ||||
| 	 */ | ||||
| 	public function __construct(Container $container, array $config = []) | ||||
| 	{ | ||||
| 		parent::__construct($container, $config); | ||||
|  | ||||
| 		$this->permissions = $this->getPermissions(null, $this->additionalPermissions); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Determines if the current Joomla! version and your current table support AJAX-powered drag and drop reordering. | ||||
| 	 * If they do, it will set up the drag & drop reordering feature. | ||||
| 	 * | ||||
| 	 * @return  null|array  Null if not supported, otherwise a table with necessary information (saveOrder: should | ||||
| 	 *                           you enable DnD reordering; orderingColumn: which column has the ordering information). | ||||
| 	 */ | ||||
| 	public function hasAjaxOrderingSupport(): ?array | ||||
| 	{ | ||||
| 		/** @var DataModel $model */ | ||||
| 		$model = $this->getModel(); | ||||
|  | ||||
| 		if (!$model->hasField('ordering')) | ||||
| 		{ | ||||
| 			return null; | ||||
| 		} | ||||
|  | ||||
| 		$listOrder       = $this->escape($model->getState('filter_order', null, 'cmd')); | ||||
| 		$listDir         = $this->escape($model->getState('filter_order_Dir', null, 'cmd')); | ||||
| 		$saveOrder       = $listOrder == $model->getFieldAlias('ordering'); | ||||
| 		$saveOrderingUrl = ''; | ||||
|  | ||||
| 		if ($saveOrder) | ||||
| 		{ | ||||
| 			$saveOrderingUrl = 'index.php?option=' . $this->container->componentName . '&view=' . $this->getName() . '&task=saveorder&format=json'; | ||||
| 			$helper          = version_compare(JVERSION, '3.999.999', 'le') ? 'sortablelist.sortable' : 'draggablelist.draggable'; | ||||
|  | ||||
| 			HtmlHelper::_($helper, 'itemsList', 'adminForm', strtolower($listDir), $saveOrderingUrl); | ||||
| 		} | ||||
|  | ||||
| 		return [ | ||||
| 			'saveOrder'      => $saveOrder, | ||||
| 			'saveOrderURL'   => $saveOrderingUrl . '&' . $this->container->platform->getToken() . '=1', | ||||
| 			'orderingColumn' => $model->getFieldAlias('ordering'), | ||||
| 		]; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns the internal list of useful variables to the benefit of header fields. | ||||
| 	 * | ||||
| 	 * @return \stdClass | ||||
| 	 */ | ||||
| 	public function getLists() | ||||
| 	{ | ||||
| 		return $this->lists; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns a reference to the permissions object of this view | ||||
| 	 * | ||||
| 	 * @return \stdClass | ||||
| 	 */ | ||||
| 	public function getPerms() | ||||
| 	{ | ||||
| 		return $this->permissions; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns a reference to the pagination object of this view | ||||
| 	 * | ||||
| 	 * @return Pagination | ||||
| 	 */ | ||||
| 	public function getPagination() | ||||
| 	{ | ||||
| 		return $this->pagination; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Get the items collection for browse views | ||||
| 	 * | ||||
| 	 * @return Collection | ||||
| 	 */ | ||||
| 	public function getItems() | ||||
| 	{ | ||||
| 		return $this->items; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Get the item for read, edit, add views | ||||
| 	 * | ||||
| 	 * @return DataModel | ||||
| 	 */ | ||||
| 	public function getItem() | ||||
| 	{ | ||||
| 		return $this->item; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Get the items count for browse views | ||||
| 	 * | ||||
| 	 * @return int | ||||
| 	 */ | ||||
| 	public function getItemCount() | ||||
| 	{ | ||||
| 		return $this->itemCount; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Get the Joomla! page parameters | ||||
| 	 * | ||||
| 	 * @return Registry | ||||
| 	 */ | ||||
| 	public function getPageParams() | ||||
| 	{ | ||||
| 		return $this->pageParams; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns a permissions object. | ||||
| 	 * | ||||
| 	 * The additionalPermissions array is a hashed array of local key => Joomla! ACL key value pairs. Local key is the | ||||
| 	 * name of the permission in the permissions object, whereas Joomla! ACL key is the name of the ACL permission | ||||
| 	 * known to Joomla! e.g. "core.manage", "foobar.something" and so on. | ||||
| 	 * | ||||
| 	 * Note: on CLI applications all permissions are set to TRUE. There is no ACL check there. | ||||
| 	 * | ||||
| 	 * @param   null|string  $component              The name of the component. Leave empty for automatic detection. | ||||
| 	 * @param   array        $additionalPermissions  Any additional permissions you want to add to the object. | ||||
| 	 * | ||||
| 	 * @return  object | ||||
| 	 */ | ||||
| 	protected function getPermissions($component = null, array $additionalPermissions = []) | ||||
| 	{ | ||||
| 		// Make sure we have a component | ||||
| 		if (empty($component)) | ||||
| 		{ | ||||
| 			$component = $this->container->componentName; | ||||
| 		} | ||||
|  | ||||
| 		// Initialise with all true | ||||
| 		$permissions = [ | ||||
| 			'create'    => true, | ||||
| 			'edit'      => true, | ||||
| 			'editown'   => true, | ||||
| 			'editstate' => true, | ||||
| 			'delete'    => true, | ||||
| 		]; | ||||
|  | ||||
| 		foreach (array_keys($additionalPermissions) as $localKey) | ||||
| 		{ | ||||
| 			$permissions[$localKey] = true; | ||||
| 		} | ||||
|  | ||||
| 		$platform = $this->container->platform; | ||||
|  | ||||
| 		// If this is a CLI application we don't make any ACL checks | ||||
| 		if ($platform->isCli()) | ||||
| 		{ | ||||
| 			return (object) $permissions; | ||||
| 		} | ||||
|  | ||||
| 		// Get the core permissions | ||||
| 		$permissions = [ | ||||
| 			'create'    => $platform->authorise('core.create', $component), | ||||
| 			'edit'      => $platform->authorise('core.edit', $component), | ||||
| 			'editown'   => $platform->authorise('core.edit.own', $component), | ||||
| 			'editstate' => $platform->authorise('core.edit.state', $component), | ||||
| 			'delete'    => $platform->authorise('core.delete', $component), | ||||
| 		]; | ||||
|  | ||||
| 		foreach ($additionalPermissions as $localKey => $joomlaPermission) | ||||
| 		{ | ||||
| 			$permissions[$localKey] = $platform->authorise($joomlaPermission, $component); | ||||
| 		} | ||||
|  | ||||
| 		return (object) $permissions; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Executes before rendering the page for the Browse task. | ||||
| 	 */ | ||||
| 	protected function onBeforeBrowse() | ||||
| 	{ | ||||
| 		// Create the lists object | ||||
| 		$this->lists = new \stdClass(); | ||||
|  | ||||
| 		// Load the model | ||||
| 		/** @var DataModel $model */ | ||||
| 		$model = $this->getModel(); | ||||
|  | ||||
| 		// We want to persist the state in the session | ||||
| 		$model->savestate(1); | ||||
|  | ||||
| 		// Display limits | ||||
| 		$defaultLimit = 20; | ||||
|  | ||||
| 		if (!$this->container->platform->isCli() && class_exists('\Joomla\CMS\Factory')) | ||||
| 		{ | ||||
| 			$app = JoomlaFactory::getApplication(); | ||||
|  | ||||
| 			$defaultLimit = method_exists($app, 'get') ? $app->get('list_limit') : 20; | ||||
| 		} | ||||
|  | ||||
| 		$this->lists->limitStart = $model->getState('limitstart', 0, 'int'); | ||||
| 		$this->lists->limit      = $model->getState('limit', $defaultLimit, 'int'); | ||||
|  | ||||
| 		$model->limitstart = $this->lists->limitStart; | ||||
| 		$model->limit      = $this->lists->limit; | ||||
|  | ||||
| 		// Assign items to the view | ||||
| 		$this->items     = $model->get(false); | ||||
| 		$this->itemCount = $model->count(); | ||||
|  | ||||
| 		// Ordering information | ||||
| 		$this->lists->order     = $model->getState('filter_order', $model->getIdFieldName(), 'cmd'); | ||||
| 		$this->lists->order_Dir = $model->getState('filter_order_Dir', null, 'cmd'); | ||||
|  | ||||
| 		if ($this->lists->order_Dir) | ||||
| 		{ | ||||
| 			$this->lists->order_Dir = strtolower($this->lists->order_Dir); | ||||
| 		} | ||||
|  | ||||
| 		// Pagination | ||||
| 		$this->pagination = new Pagination($this->itemCount, $this->lists->limitStart, $this->lists->limit); | ||||
|  | ||||
| 		// Pass page params on frontend only | ||||
| 		if ($this->container->platform->isFrontend()) | ||||
| 		{ | ||||
| 			/** @var SiteApplication $app */ | ||||
| 			$app              = JoomlaFactory::getApplication(); | ||||
| 			$params           = $app->getParams(); | ||||
| 			$this->pageParams = $params; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Executes before rendering the page for the add task. | ||||
| 	 */ | ||||
| 	protected function onBeforeAdd() | ||||
| 	{ | ||||
| 		/** @var DataModel $model */ | ||||
| 		$model = $this->getModel(); | ||||
|  | ||||
| 		/** | ||||
| 		 * The model is pushed into the View by the Controller. As you can see in DataController::add() it is possible | ||||
| 		 * to push both default values (defaultsForAdd) as well as data from the state (e.g. when saving a new record | ||||
| 		 * failed for some reason and the user needs to edit it). That's why we populate defaultFields from $model. We | ||||
| 		 * still do a full reset on a clone of the Model to get a clean object and merge default values (instead of null | ||||
| 		 * values) with the data pushed by the controller. | ||||
| 		 */ | ||||
| 		$defaultFields = $model->getData(); | ||||
| 		$this->item    = $model->getClone()->reset(true, true); | ||||
|  | ||||
| 		foreach ($defaultFields as $k => $v) | ||||
| 		{ | ||||
| 			try | ||||
| 			{ | ||||
| 				$this->item->setFieldValue($k, $v); | ||||
| 			} | ||||
| 			catch (\Exception $e) | ||||
| 			{ | ||||
| 				// Suppress errors in field assignments at this stage | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Executes before rendering the page for the Edit task. | ||||
| 	 */ | ||||
| 	protected function onBeforeEdit() | ||||
| 	{ | ||||
| 		/** @var DataModel $model */ | ||||
| 		$model = $this->getModel(); | ||||
|  | ||||
| 		// It seems that I can't edit records, maybe I can edit only this one due asset tracking? | ||||
| 		if ((!$this->permissions->edit || !$this->permissions->editown) && is_object($model) && ($model instanceof DataModel)) | ||||
| 		{ | ||||
| 			// Make sure the model is really asset tracked | ||||
| 			$assetName       = $model->getAssetName(); | ||||
| 			$assetName       = is_string($assetName) ? $assetName : null; | ||||
| 			$isAssetsTracked = $model->isAssetsTracked() && !empty($assetName); | ||||
|  | ||||
| 			// Ok, record is tracked, let's see if I can this record | ||||
| 			if ($isAssetsTracked) | ||||
| 			{ | ||||
| 				$platform = $this->container->platform; | ||||
|  | ||||
|  | ||||
| 				if (!$this->permissions->edit && !is_null($assetName)) | ||||
| 				{ | ||||
| 					$this->permissions->edit = $platform->authorise('core.edit', $assetName); | ||||
| 				} | ||||
|  | ||||
| 				if (!$this->permissions->editown && !is_null($assetName)) | ||||
| 				{ | ||||
| 					$this->permissions->editown = $platform->authorise('core.edit.own', $assetName); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		$this->item = $model->findOrFail(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Executes before rendering the page for the Read task. | ||||
| 	 */ | ||||
| 	protected function onBeforeRead() | ||||
| 	{ | ||||
| 		/** @var DataModel $model */ | ||||
| 		$model = $this->getModel(); | ||||
|  | ||||
| 		$this->item = $model->findOrFail(); | ||||
| 	} | ||||
| }  | ||||
		Reference in New Issue
	
	Block a user