如何在 TYPO3 中增强 fe_users?
How can I enhance fe_users in TYPO3?
我想根据 table fe_users
.phone 编写一本 phone 书。
所以我使用 EXT:extensionbuilder 来增强某些字段的 table。使用该存根,我尝试构建一些列表(具有不同分组和排序的多个视图)和一个详细视图。
虽然在数据库中插入了额外的字段并且可以从 extensionbuilder 生成的代码中获得插件,但我在使视图正常工作方面遇到了很大的问题。
起初列表视图错过了很多。我添加了对起始页和递归深度的控制,并将这些参数添加到存储库的 findAll()
方法中。
由于生成的代码无法以任何方式工作,我不得不完全替换它,并且还需要在我继承的域模型中插入所有给定的字段(只需要一个声明,不需要 getter()
或 setter()
)
现在我想让详细视图(show
操作)起作用。
因此我需要在存储库 class 的 findByUid()
中插入工作代码。正如列表视图体验所预期的那样,生成的代码也不起作用。
第一个错误:
(1/2) #1297759968 TYPO3\CMS\Extbase\Property\Exception
Exception while property mapping at property path "": It is not allowed to map property "address".
You need to use $propertyMappingConfiguration->allowProperties('address') to enable mapping of this property.
因为我插入的每个字段都重复错误:
public function initializeShowAction() {
$propertyMappingConfiguration = $this->arguments['phonebookItem']->getPropertyMappingConfiguration();
// allow all properties:
$propertyMappingConfiguration->allowAllProperties();
$propertyMappingConfiguration->allowCreationForSubProperty('Tx_Phonebook_PhonebookItem');
// or just allow certain properties
//$propertyMappingConfiguration->allowProperties('address');
}
在我继承的存储库中。
现在我的错误是:
(1/2) #1297759968 TYPO3\CMS\Extbase\Property\Exception
Exception while property mapping at property path "": Creation of objects not allowed.
To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_CREATION_ALLOWED" to TRUE
我不知道在哪里设置这个值。
欢迎任何帮助。甚至是展示的完整替代品。
我坚持使用 fe_useres
,因为这是从存储信息的 AD 获取数据的唯一方法。否则我需要一个额外的导入器来将数据从 AD 导入到其他记录中。
编辑:我的文件
Classes/Controller/PhonebookItemController.php
:
<?php
namespace Vendor\Phonebook\Domain\Model;
/**
* PhonebookItem
*/
class PhonebookItem extends \TYPO3\CMS\Extbase\Domain\Model\FrontendUser
{
// Declaration of all new fields and their getter and setter
// like:
/**
* office
*
* @var string
*/
protected $office = '';
/**
* Returns the office
*
* @return string $office
*/
public function getOffice()
{
return $this->office;
}
/**
* Sets the office
*
* @param string $office
* @return void
*/
public function setOffice($office)
{
$this->office = $office;
}
// meanwhile additional: declaration of all fields of the core fields to table fe_users
// like:
/**
* @var string
*/
protected $name = '';
}
Classes/Domain/Repository/PhonebookItemRepository.php
:
<?php
namespace Vendor\Phonebook\Domain\Repository;
use Vendor\Phonebook\Domain\Model\PhonebookItem;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
use TYPO3\CMS\Extbase\Persistence\Repository;
use TYPO3\CMS\Core\Database\ConnectionPool;
/**
* Class PhonebookItemRepository
*/
class PhonebookItemRepository extends Repository
{
public function __construct(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager = NULL) {
if (!$objectManager) {
$objectManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
}
$this->objectType = Vendor\Phonebook\Domain\Model\PhonebookItem::class;
parent::__construct($objectManager);
}
public function findAll($startPage = 0,$recursive = 0)
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('fe_users');
$pidList = $startPage;
if ($recursive) {
$queryGenerator = $this->objectManager->get('TYPO3\CMS\Core\Database\QueryGenerator');
$pidList = $queryGenerator->getTreeList($startPage, $recursive, 0, '1');
}
$rows = $queryBuilder
// Select one ore more fields …
->select('*')
// … from a table …
->from('fe_users')
// … that fits into this condition.
->where(
// This looks a bit strange, but ensures that the condition is coded in the most suitable way for the database.
$queryBuilder->expr()->in('pid', $pidList, true)
)
->orderBy('username', 'ASC')
->orderBy('name','ASC')
->orderBy('first_name','ASC')
->orderBy('last_name','ASC')
// Run the query …
->execute()
// … and fetch all results as an associative array.
->fetchAll();
return $rows;
/* == Original code from ExtensionBuilder: ==
$this->objectType = Vendor\Phonebook\Domain\Model\PhonebookItem::class;
$query = $this->createQuery();
$this->ignoreEnableFieldsAndStoragePage($query);
$query->getQuerySettings()->setRespectSysLanguage(false);
//$and = [$query->equals('uid', $uid)];
/// @var PhonebookItem $phonebookItem
$phonebookItems = $query
// ->matching($query->logicalAnd($and))
->execute();
return $phonebookItems;
*/
}
}
/Classes/Controller/PhonebookitemController.php
:
<?php
namespace Vendor\Phonebook\Controller;
use Vendor\phonebook\Domain\Repository\PhonebookItemRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
/**
* PhonebookItemController
*/
class PhonebookItemController extends ActionController
{
public $phonebookItemRepository;
public $cobj = NULL;
public $startPage;
public $recursive;
public function __construct() {
$this->phonebookItemRepository = GeneralUtility::makeInstance(\Vendor\Phonebook\Domain\Repository\PhonebookItemRepository::class);
}
/**
* action list
*
* @return void
*/
public function listAction()
{
$this->cObj = $this->configurationManager->getContentObject();
$this->startPage = ($this->settings['pages' ] ?? $this->cObj->data['pages' ]) ?? $this->cObj->data['pid'];
$this->recursive = ($this->settings['recursive'] ?? $this->cObj->data['recursive']) ?? 0;
switch ($this->settings['plugintype']) {
case 'listemployee':
$this->listEmployeeAction();
break;
case 'listoffice':
$this->listOfficeAction();
break;
default:
$phonebookItems = $this->phonebookItemRepository->findAll($this->startPage, $this->recursive);
$this->view->assign('phonebookItems', $phonebookItems);
break;
}
}
public function initializeShowAction() {
$propertyMappingConfiguration = $this->arguments['phonebookItem']->getPropertyMappingConfiguration();
// allow all properties:
$propertyMappingConfiguration->allowAllProperties();
$propertyMappingConfiguration->allowCreationForSubProperty('Tx_Phonebook_PhonebookItem');
// or just allow certain properties
//$propertyMappingConfiguration->allowProperties('address');
}
/**
* action show
*
* @param \Vendor\Phonebook\Domain\Model\PhonebookItem $phonebookItem
* @return void
*/
public function showAction(\Itkr\Phonebook\Domain\Model\PhonebookItem $phonebookItem)
{
$this->view->assign('phonebookItem', $phonebookItem);
}
/**
* action listEmployee
*
* @return void
*/
public function listEmployeeAction()
{
$phonebookItems = $this->phonebookItemRepository->findAll($this->startPage, $this->recursive);
$this->view->assign('phonebookItems', $phonebookItems);
}
/**
* action listOffice
*
* @return void
*/
public function listOfficeAction()
{
$phonebookItems = $this->phonebookItemRepository->findAll($this->startPage, $this->recursive);
$this->view->assign('phonebookItems', $phonebookItems);
}
}
解法:
正如丹尼尔提到的:
detail-/show-link 的参数是错误的。
将 url 更改为正确的格式 (<f:variable name="showUrl" value="{f:uri.action(action:'show',arguments:{phonebookItem : entry.uid})}" />
) 后,不再需要所有其他方法和变量声明。
上述行为是Extbase的一种安全机制。
Extbase 不允许通过 GET 请求修改存储记录的数据。
你大概是通过GET请求方式调用了showAction,提交了数据。它们不允许被映射,这是一件好事。不好的是你需要弄清楚为什么通过请求提交那些字段。
所以问题是你的模板,或者你在哪里构建请求/url。
不需要你的initializeAction。
也不要为 storagePid 构建自定义逻辑,坚持使用 tt_content 中的现有字段,extbase 将开箱即用。
我认为您应该使用 Typoscript 配置扩展前端用户模型,然后调整模型、存储库并为电话簿项目创建控制器。示例:https://extcode.github.io/cart_snippets/posts/how-to-extend-product-models-part-one
我想根据 table fe_users
.phone 编写一本 phone 书。
所以我使用 EXT:extensionbuilder 来增强某些字段的 table。使用该存根,我尝试构建一些列表(具有不同分组和排序的多个视图)和一个详细视图。
虽然在数据库中插入了额外的字段并且可以从 extensionbuilder 生成的代码中获得插件,但我在使视图正常工作方面遇到了很大的问题。
起初列表视图错过了很多。我添加了对起始页和递归深度的控制,并将这些参数添加到存储库的 findAll()
方法中。
由于生成的代码无法以任何方式工作,我不得不完全替换它,并且还需要在我继承的域模型中插入所有给定的字段(只需要一个声明,不需要 getter()
或 setter()
)
现在我想让详细视图(show
操作)起作用。
因此我需要在存储库 class 的 findByUid()
中插入工作代码。正如列表视图体验所预期的那样,生成的代码也不起作用。
第一个错误:
(1/2) #1297759968 TYPO3\CMS\Extbase\Property\Exception
Exception while property mapping at property path "": It is not allowed to map property "address".
You need to use $propertyMappingConfiguration->allowProperties('address') to enable mapping of this property.
因为我插入的每个字段都重复错误:
public function initializeShowAction() {
$propertyMappingConfiguration = $this->arguments['phonebookItem']->getPropertyMappingConfiguration();
// allow all properties:
$propertyMappingConfiguration->allowAllProperties();
$propertyMappingConfiguration->allowCreationForSubProperty('Tx_Phonebook_PhonebookItem');
// or just allow certain properties
//$propertyMappingConfiguration->allowProperties('address');
}
在我继承的存储库中。
现在我的错误是:
(1/2) #1297759968 TYPO3\CMS\Extbase\Property\Exception
Exception while property mapping at property path "": Creation of objects not allowed.
To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_CREATION_ALLOWED" to TRUE
我不知道在哪里设置这个值。
欢迎任何帮助。甚至是展示的完整替代品。
我坚持使用 fe_useres
,因为这是从存储信息的 AD 获取数据的唯一方法。否则我需要一个额外的导入器来将数据从 AD 导入到其他记录中。
编辑:我的文件
Classes/Controller/PhonebookItemController.php
:
<?php
namespace Vendor\Phonebook\Domain\Model;
/**
* PhonebookItem
*/
class PhonebookItem extends \TYPO3\CMS\Extbase\Domain\Model\FrontendUser
{
// Declaration of all new fields and their getter and setter
// like:
/**
* office
*
* @var string
*/
protected $office = '';
/**
* Returns the office
*
* @return string $office
*/
public function getOffice()
{
return $this->office;
}
/**
* Sets the office
*
* @param string $office
* @return void
*/
public function setOffice($office)
{
$this->office = $office;
}
// meanwhile additional: declaration of all fields of the core fields to table fe_users
// like:
/**
* @var string
*/
protected $name = '';
}
Classes/Domain/Repository/PhonebookItemRepository.php
:
<?php
namespace Vendor\Phonebook\Domain\Repository;
use Vendor\Phonebook\Domain\Model\PhonebookItem;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
use TYPO3\CMS\Extbase\Persistence\Repository;
use TYPO3\CMS\Core\Database\ConnectionPool;
/**
* Class PhonebookItemRepository
*/
class PhonebookItemRepository extends Repository
{
public function __construct(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager = NULL) {
if (!$objectManager) {
$objectManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
}
$this->objectType = Vendor\Phonebook\Domain\Model\PhonebookItem::class;
parent::__construct($objectManager);
}
public function findAll($startPage = 0,$recursive = 0)
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('fe_users');
$pidList = $startPage;
if ($recursive) {
$queryGenerator = $this->objectManager->get('TYPO3\CMS\Core\Database\QueryGenerator');
$pidList = $queryGenerator->getTreeList($startPage, $recursive, 0, '1');
}
$rows = $queryBuilder
// Select one ore more fields …
->select('*')
// … from a table …
->from('fe_users')
// … that fits into this condition.
->where(
// This looks a bit strange, but ensures that the condition is coded in the most suitable way for the database.
$queryBuilder->expr()->in('pid', $pidList, true)
)
->orderBy('username', 'ASC')
->orderBy('name','ASC')
->orderBy('first_name','ASC')
->orderBy('last_name','ASC')
// Run the query …
->execute()
// … and fetch all results as an associative array.
->fetchAll();
return $rows;
/* == Original code from ExtensionBuilder: ==
$this->objectType = Vendor\Phonebook\Domain\Model\PhonebookItem::class;
$query = $this->createQuery();
$this->ignoreEnableFieldsAndStoragePage($query);
$query->getQuerySettings()->setRespectSysLanguage(false);
//$and = [$query->equals('uid', $uid)];
/// @var PhonebookItem $phonebookItem
$phonebookItems = $query
// ->matching($query->logicalAnd($and))
->execute();
return $phonebookItems;
*/
}
}
/Classes/Controller/PhonebookitemController.php
:
<?php
namespace Vendor\Phonebook\Controller;
use Vendor\phonebook\Domain\Repository\PhonebookItemRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
/**
* PhonebookItemController
*/
class PhonebookItemController extends ActionController
{
public $phonebookItemRepository;
public $cobj = NULL;
public $startPage;
public $recursive;
public function __construct() {
$this->phonebookItemRepository = GeneralUtility::makeInstance(\Vendor\Phonebook\Domain\Repository\PhonebookItemRepository::class);
}
/**
* action list
*
* @return void
*/
public function listAction()
{
$this->cObj = $this->configurationManager->getContentObject();
$this->startPage = ($this->settings['pages' ] ?? $this->cObj->data['pages' ]) ?? $this->cObj->data['pid'];
$this->recursive = ($this->settings['recursive'] ?? $this->cObj->data['recursive']) ?? 0;
switch ($this->settings['plugintype']) {
case 'listemployee':
$this->listEmployeeAction();
break;
case 'listoffice':
$this->listOfficeAction();
break;
default:
$phonebookItems = $this->phonebookItemRepository->findAll($this->startPage, $this->recursive);
$this->view->assign('phonebookItems', $phonebookItems);
break;
}
}
public function initializeShowAction() {
$propertyMappingConfiguration = $this->arguments['phonebookItem']->getPropertyMappingConfiguration();
// allow all properties:
$propertyMappingConfiguration->allowAllProperties();
$propertyMappingConfiguration->allowCreationForSubProperty('Tx_Phonebook_PhonebookItem');
// or just allow certain properties
//$propertyMappingConfiguration->allowProperties('address');
}
/**
* action show
*
* @param \Vendor\Phonebook\Domain\Model\PhonebookItem $phonebookItem
* @return void
*/
public function showAction(\Itkr\Phonebook\Domain\Model\PhonebookItem $phonebookItem)
{
$this->view->assign('phonebookItem', $phonebookItem);
}
/**
* action listEmployee
*
* @return void
*/
public function listEmployeeAction()
{
$phonebookItems = $this->phonebookItemRepository->findAll($this->startPage, $this->recursive);
$this->view->assign('phonebookItems', $phonebookItems);
}
/**
* action listOffice
*
* @return void
*/
public function listOfficeAction()
{
$phonebookItems = $this->phonebookItemRepository->findAll($this->startPage, $this->recursive);
$this->view->assign('phonebookItems', $phonebookItems);
}
}
解法:
正如丹尼尔提到的:
detail-/show-link 的参数是错误的。
将 url 更改为正确的格式 (<f:variable name="showUrl" value="{f:uri.action(action:'show',arguments:{phonebookItem : entry.uid})}" />
) 后,不再需要所有其他方法和变量声明。
上述行为是Extbase的一种安全机制。 Extbase 不允许通过 GET 请求修改存储记录的数据。
你大概是通过GET请求方式调用了showAction,提交了数据。它们不允许被映射,这是一件好事。不好的是你需要弄清楚为什么通过请求提交那些字段。
所以问题是你的模板,或者你在哪里构建请求/url。
不需要你的initializeAction。
也不要为 storagePid 构建自定义逻辑,坚持使用 tt_content 中的现有字段,extbase 将开箱即用。
我认为您应该使用 Typoscript 配置扩展前端用户模型,然后调整模型、存储库并为电话簿项目创建控制器。示例:https://extcode.github.io/cart_snippets/posts/how-to-extend-product-models-part-one