Initial commit
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Content;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\SlideViewHelperTrait;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ### Base class: Content ViewHelpers
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @author Dominique Feyer, <dfeyer@ttree.ch>
|
||||
* @author Daniel Schöne, <daniel@schoene.it>
|
||||
* @author Björn Fromme, <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @author Danilo Bürger <danilo.buerger@hmspl.de>, Heimspiel GmbH
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Content
|
||||
*/
|
||||
abstract class AbstractContentViewHelper extends AbstractViewHelper {
|
||||
|
||||
use SlideViewHelperTrait;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager
|
||||
* @return void
|
||||
*/
|
||||
public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager) {
|
||||
$this->configurationManager = $configurationManager;
|
||||
$this->contentObject = $configurationManager->getContentObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerArgument('column', 'integer', 'Name of the column to render', FALSE, 0);
|
||||
$this->registerArgument('order', 'string', 'Optional sort field of content elements - RAND() supported. Note that when sliding is enabled, the sorting will be applied to records on a per-page basis and not to the total set of collected records.', FALSE, 'sorting');
|
||||
$this->registerArgument('sortDirection', 'string', 'Optional sort direction of content elements', FALSE, 'ASC');
|
||||
$this->registerArgument('pageUid', 'integer', 'If set, selects only content from this page UID', FALSE, 0);
|
||||
$this->registerArgument('contentUids', 'array', 'If used, replaces all conditions with an "uid IN (1,2,3)" style condition using the UID values from this array');
|
||||
$this->registerArgument('sectionIndexOnly', 'boolean', 'If TRUE, only renders/gets content that is marked as "include in section index"', FALSE, FALSE);
|
||||
$this->registerArgument('loadRegister', 'array', 'List of LOAD_REGISTER variable');
|
||||
$this->registerArgument('render', 'boolean', 'Optional returning variable as original table rows', FALSE, TRUE);
|
||||
$this->registerArgument('hideUntranslated', 'boolean', 'If FALSE, will NOT include elements which have NOT been translated, if current language is NOT the default language. Default is to show untranslated elements but never display the original if there is a translated version', FALSE, FALSE);
|
||||
$this->registerSlideArguments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content records based on column and pid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getContentRecords() {
|
||||
$limit = $this->arguments['limit'];
|
||||
|
||||
$pageUid = $this->getPageUid();
|
||||
|
||||
$contentRecords = $this->getSlideRecords($pageUid, $limit);
|
||||
|
||||
if (TRUE === (boolean) $this->arguments['render']) {
|
||||
$contentRecords = $this->getRenderedRecords($contentRecords);
|
||||
}
|
||||
|
||||
return $contentRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $pageUid
|
||||
* @param integer $limit
|
||||
* @return array[]
|
||||
*/
|
||||
protected function getSlideRecordsFromPage($pageUid, $limit) {
|
||||
$column = (integer) $this->arguments['column'];
|
||||
$order = $this->arguments['order'];
|
||||
if (FALSE === empty($order)) {
|
||||
$sortDirection = strtoupper(trim($this->arguments['sortDirection']));
|
||||
if ('ASC' !== $sortDirection && 'DESC' !== $sortDirection) {
|
||||
$sortDirection = 'ASC';
|
||||
}
|
||||
$order = $order . ' ' . $sortDirection;
|
||||
}
|
||||
$contentUids = $this->arguments['contentUids'];
|
||||
if (TRUE === is_array($contentUids)) {
|
||||
$conditions = 'uid IN (' . implode(',', $contentUids) . ')';
|
||||
} else {
|
||||
$hideUntranslated = (boolean) $this->arguments['hideUntranslated'];
|
||||
$currentLanguage = $GLOBALS['TSFE']->sys_language_content;
|
||||
$languageCondition = '(sys_language_uid IN (-1,' . $currentLanguage . ')';
|
||||
if (0 < $currentLanguage) {
|
||||
if (TRUE === $hideUntranslated) {
|
||||
$languageCondition .= ' AND l18n_parent > 0';
|
||||
}
|
||||
$nestedQuery = $GLOBALS['TYPO3_DB']->SELECTquery('l18n_parent', 'tt_content', 'sys_language_uid = ' .
|
||||
$currentLanguage . $GLOBALS['TSFE']->cObj->enableFields('tt_content'));
|
||||
$languageCondition .= ' AND uid NOT IN (' . $nestedQuery . ')';
|
||||
}
|
||||
$languageCondition .= ')';
|
||||
$conditions = "pid = '" . (integer) $pageUid . "' AND colPos = '" . (integer) $column . "'" .
|
||||
$GLOBALS['TSFE']->cObj->enableFields('tt_content') . ' AND ' . $languageCondition;
|
||||
}
|
||||
if (TRUE === (boolean) $this->arguments['sectionIndexOnly']) {
|
||||
$conditions .= ' AND sectionIndex = 1';
|
||||
}
|
||||
|
||||
$rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'tt_content', $conditions, '', $order, $limit);
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configured, or the current page UID if
|
||||
* none is configured in arguments and no content_from_pid
|
||||
* value exists in the current page record's attributes.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
protected function getPageUid() {
|
||||
$pageUid = (integer) $this->arguments['pageUid'];
|
||||
if (1 > $pageUid) {
|
||||
$pageUid = (integer) $GLOBALS['TSFE']->page['content_from_pid'];
|
||||
}
|
||||
if (1 > $pageUid) {
|
||||
$pageUid = (integer) $GLOBALS['TSFE']->id;
|
||||
}
|
||||
return $pageUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function renders an array of tt_content record into an array of rendered content
|
||||
* it returns a list of elements rendered by typoscript RECORD function
|
||||
*
|
||||
* @param array $rows database rows of records (each item is a tt_content table record)
|
||||
* @return array
|
||||
*/
|
||||
protected function getRenderedRecords(array $rows) {
|
||||
if (FALSE === empty($this->arguments['loadRegister'])) {
|
||||
$this->contentObject->cObjGetSingle('LOAD_REGISTER', $this->arguments['loadRegister']);
|
||||
}
|
||||
$elements = array();
|
||||
foreach ($rows as $row) {
|
||||
array_push($elements, $this->renderRecord($row));
|
||||
}
|
||||
if (FALSE === empty($this->arguments['loadRegister'])) {
|
||||
$this->contentObject->cObjGetSingle('RESTORE_REGISTER', '');
|
||||
}
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function renders a raw tt_content record into the corresponding
|
||||
* element by typoscript RENDER function. We keep track of already
|
||||
* rendered records to avoid rendering the same record twice inside the
|
||||
* same nested stack of content elements.
|
||||
*
|
||||
* @param array $row
|
||||
* @return string|NULL
|
||||
*/
|
||||
protected function renderRecord(array $row) {
|
||||
if (0 < $GLOBALS['TSFE']->recordRegister['tt_content:' . $row['uid']]) {
|
||||
return NULL;
|
||||
}
|
||||
$conf = array(
|
||||
'tables' => 'tt_content',
|
||||
'source' => $row['uid'],
|
||||
'dontCheckPid' => 1
|
||||
);
|
||||
$parent = $GLOBALS['TSFE']->currentRecord;
|
||||
// If the currentRecord is set, we register, that this record has invoked this function.
|
||||
// It's should not be allowed to do this again then!!
|
||||
if (FALSE === empty($parent)) {
|
||||
++$GLOBALS['TSFE']->recordRegister[$parent];
|
||||
}
|
||||
$html = $GLOBALS['TSFE']->cObj->cObjGetSingle('RECORDS', $conf);
|
||||
|
||||
$GLOBALS['TSFE']->currentRecord = $parent;
|
||||
if (FALSE === empty($parent)) {
|
||||
--$GLOBALS['TSFE']->recordRegister[$parent];
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Content;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ViewHelper used to render content elements in Fluid page templates
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @author Dominique Feyer, <dfeyer@ttree.ch>
|
||||
* @author Daniel Schöne, <daniel@schoene.it>
|
||||
* @author Björn Fromme, <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Content
|
||||
*/
|
||||
class GetViewHelper extends AbstractContentViewHelper {
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->overrideArgument('render', 'boolean', 'Optional returning variable as original table rows', FALSE, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render() {
|
||||
if ('BE' === TYPO3_MODE) {
|
||||
return '';
|
||||
}
|
||||
$contentRecords = $this->getContentRecords();
|
||||
return $contentRecords;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Content;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper to access data of the current content element record
|
||||
*
|
||||
* @author Benjamin Rau <rau@codearts.at>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Content
|
||||
*/
|
||||
class InfoViewHelper extends AbstractViewHelper {
|
||||
|
||||
use TemplateVariableViewHelperTrait;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface An instance of the Configuration Manager
|
||||
* @return void
|
||||
*/
|
||||
public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager) {
|
||||
$this->configurationManager = $configurationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerAsArgument();
|
||||
$this->registerArgument('contentUid', 'integer', 'If specified, this UID will be used to fetch content element data instead of using the current content element.', FALSE, 0);
|
||||
$this->registerArgument('field', 'string', 'If specified, only this field will be returned/assigned instead of the complete content element record.', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function render() {
|
||||
$contentUid = intval($this->arguments['contentUid']);
|
||||
if (0 === $contentUid) {
|
||||
$cObj = $this->configurationManager->getContentObject();
|
||||
$record = $cObj->data;
|
||||
}
|
||||
|
||||
$field = $this->arguments['field'];
|
||||
|
||||
if (FALSE === isset($record) && 0 !== $contentUid) {
|
||||
if (NULL !== $field && TRUE === isset($GLOBALS['TCA']['tt_content']['columns'][$field])) {
|
||||
$selectFields = $field;
|
||||
} else {
|
||||
$selectFields = '*';
|
||||
}
|
||||
$record = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow($selectFields, 'tt_content', sprintf('uid=%d', $contentUid));
|
||||
|
||||
// Add the page overlay
|
||||
$languageUid = intval($GLOBALS['TSFE']->sys_language_uid);
|
||||
if (0 !== $languageUid && $GLOBALS['TSFE']->sys_language_contentOL) {
|
||||
$record = $GLOBALS['TSFE']->sys_page->getRecordOverlay('tt_content', $record, $GLOBALS['TSFE']->sys_language_content, $GLOBALS['TSFE']->sys_language_contentOL);
|
||||
}
|
||||
}
|
||||
|
||||
if (FALSE === $record && FALSE === isset($record)) {
|
||||
throw new \Exception(sprintf('Either record with uid %d or field %s do not exist.', $contentUid, $selectFields), 1358679983);
|
||||
}
|
||||
|
||||
// Check if single field or whole record should be returned
|
||||
$content = NULL;
|
||||
if (NULL === $field) {
|
||||
$content = $record;
|
||||
} elseif (TRUE === isset($record[$field])) {
|
||||
$content = $record[$field];
|
||||
}
|
||||
|
||||
return $this->renderChildrenWithVariableOrReturnInput($content);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Content\Random;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\ViewHelpers\Content\Random\RenderViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper for fetching a random content element in Fluid page templates
|
||||
*
|
||||
* @author Björn Fromme, <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Content\Random
|
||||
*/
|
||||
class GetViewHelper extends RenderViewHelper {
|
||||
|
||||
/**
|
||||
* Initialize ViewHelper arguments
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->overrideArgument('render', 'boolean', 'Optional returning variable as original table rows', FALSE, FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Content\Random;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\ViewHelpers\Content\AbstractContentViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper for rendering a random content element in Fluid page templates
|
||||
*
|
||||
* @author Björn Fromme, <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Content\Random
|
||||
*/
|
||||
class RenderViewHelper extends AbstractContentViewHelper {
|
||||
|
||||
/**
|
||||
* Initialize ViewHelper arguments
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->overrideArgument('limit', 'integer', 'Optional limit to the number of content elements to render', FALSE, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render() {
|
||||
if ('BE' === TYPO3_MODE) {
|
||||
return '';
|
||||
}
|
||||
// Remove limit for getContentRecords()
|
||||
$limit = $this->arguments['limit'];
|
||||
$this->arguments['limit'] = NULL;
|
||||
// Just using getContentRecords with a limit of 1 would not support
|
||||
// using slideCollect as collecting would stop as soon as one record
|
||||
// was found. As a potential optimization, $render could be overrided
|
||||
// so all the content records that end up unused do not get rendered.
|
||||
$contentRecords = $this->getContentRecords();
|
||||
if (FALSE === empty($contentRecords)) {
|
||||
shuffle($contentRecords);
|
||||
$contentRecords = array_slice($contentRecords, 0, $limit);
|
||||
if (TRUE === (boolean) $this->arguments['render']) {
|
||||
$contentRecords = implode(LF, $contentRecords);
|
||||
}
|
||||
}
|
||||
return $contentRecords;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Content;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
|
||||
|
||||
/**
|
||||
* ViewHelper used to render content elements in Fluid page templates
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @author Dominique Feyer, <dfeyer@ttree.ch>
|
||||
* @author Daniel Schöne, <daniel@schoene.it>
|
||||
* @author Björn Fromme, <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Content
|
||||
*/
|
||||
class RenderViewHelper extends AbstractContentViewHelper {
|
||||
|
||||
use TemplateVariableViewHelperTrait;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->registerAsArgument();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
if ('BE' === TYPO3_MODE) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$content = $this->getContentRecords();
|
||||
if (FALSE === $this->hasArgument('as')) {
|
||||
$content = implode(LF, $content);
|
||||
}
|
||||
|
||||
return $this->renderChildrenWithVariableOrReturnInput($content);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Content\Resources;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author Danilo Bürger <danilo.buerger@hmspl.de>, Heimspiel GmbH
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Content\Resources
|
||||
*/
|
||||
class FalViewHelper extends \FluidTYPO3\Vhs\ViewHelpers\Resource\Record\FalViewHelper {
|
||||
|
||||
const defaultTable = 'tt_content';
|
||||
const defaultField = 'image';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = self::defaultTable;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $field = self::defaultField;
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
|
||||
$this->overrideArgument('table', 'string', 'The table to lookup records.', FALSE, self::defaultTable);
|
||||
$this->overrideArgument('field', 'string', 'The field of the table associated to resources.', FALSE, self::defaultField);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Content;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\ViewHelpers\Resource\RecordViewHelper;
|
||||
|
||||
/**
|
||||
* @author Danilo Bürger <danilo.buerger@hmspl.de>, Heimspiel GmbH
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Content
|
||||
*/
|
||||
class ResourcesViewHelper extends RecordViewHelper {
|
||||
|
||||
const defaultTable = 'tt_content';
|
||||
const defaultField = 'image';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = self::defaultTable;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $field = self::defaultField;
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
|
||||
$this->overrideArgument('table', 'string', 'The table to lookup records.', FALSE, self::defaultTable);
|
||||
$this->overrideArgument('field', 'string', 'The field of the table associated to resources.', FALSE, self::defaultField);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user