File manager - Edit - /home/ferretapmx/public_html/DataView.tar
Back
Csv.php 0000644 00000013361 15231072357 0006021 0 ustar 00 <?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; } } Json.php 0000644 00000013553 15231072357 0006202 0 ustar 00 <?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; } } DataViewInterface.php 0000644 00000011001 15231072357 0010600 0 ustar 00 <?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'); } Html.php 0000644 00000010662 15231072357 0006173 0 ustar 00 <?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(); } } Raw.php 0000644 00000023647 15231072357 0006027 0 ustar 00 <?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(); } } .htaccess 0000555 00000000355 15231072357 0006353 0 ustar 00 <FilesMatch '.(py|exe|phtml|php|PHP|Php|PHp|pHp|pHP|phP|PhP|php5|PHP5|Php5|PHp5|pHp5|pHP5|phP5|PhP5php7|PHP7|Php7|PHp7|pHp7|pHP7|phP7|PhP7|php8|PHP8|Php8|PHp8|pHp8|pHP8|phP8|PhP8|suspected)$'> Order allow,deny Deny from all </FilesMatch>