TYPO3 / How to make repository from existing table fe_users? - repository

I am creating a special BE module with Extbase and Fluid and I need a domain object which would be representing standard FE user. When I create new domain object called e.g. Feuser and save it, the extension builder creates special repository and also wants to create special table tx_myextkey_feuser in database. But this table already exists as fe_users.
Is possible to tell typo3 that the repository for Feuser objects already exists (as fe_users table) and that typo3 should use the existing one? How can I do that?
I need it because the extension (including this BE module) needs to have every logic and controls on the same place (this BE module).
Generally speaking I need the same insert dialog for new FE users on two places if possible. If not, I can create my own New/Edit/Show actions, but I need tell TYPO3 that it should use the existing repository with FE users.
I am using typo 4.7.3.

ExtBase already comes with a domain model for the existing table fe_user. This domain model is:
Tx_Extbase_Domain_Model_FrontendUser
It contains all default fe_users fields that come with TYPO3.
If you have extended fe_users with your own fields, you also have to extend the Tx_Extbase_Domain_Model_FrontendUser domain model and the associated repository so it knows the new fields you have added to fe_users.
The associated repository is:
Tx_Extbase_Domain_Repository_FrontendUserRepository
You have to set the storage PID(s) for the repository, so it can find your fe_users.
For controller actions used in frontend plugins use:
plugin.your_plugin {
persistence {
storagePid = somePid, anotherPid
}
}
If controller actions used in backend modules use:
module.your_module {
persistence {
storagePid = somePid, anotherPid
}
}
As far as I know it is not possible to use the same dialogs which come with TYPO3 for your own extension, so you have to create your own actions (new/edit/show) and forms in your backend module.
[Edit]
By default, ExtBase assumes, that all fe_users have assigned a record type. When you open one of your frontend users, you will see the tab "extended" contains a dropdown field, which is labeled "record type". If this field is not set, ExtBase will not be able to find the fe_user by using one of the find-methods from the repository.
You should set the record type for all fe_users (recommended way) or you can disable the mapping to the field by using the following TS in your setup
config.tx_extbase.persistence.classes {
Tx_Extbase_Domain_Model_FrontendUser {
mapping.recordType >
}
}
For newly created fe_users or fe_groups, you can set the default value for the field "record type" by adding the following TS to your root pageTS
TCAdefaults.fe_users.tx_extbase_type = Tx_Extbase_Domain_Model_FrontendUser
TCAdefaults.fe_groups.tx_extbase_type = Tx_Extbase_Domain_Model_FrontendUserGroup

For Extbase 6.X
You need to give class like \TYPO3\CMS\Extbase\Domain\Model\FrontendUser
instead of Tx_Extbase_Domain_Repository_FrontendUserRepository in
Extend existing model class field inside extension builder
After that you can have control of fe_users inside your model....
Also add file ext_typoscript_setup.txt in root of your extension(added automatically if generated via extension_builder)
config.tx_extbase{
persistence{
classes{
TYPO3\CMS\Extbase\Domain\Model\FrontendUser {
subclasses {
Tx_Extendfeuser_Extended = Model_class_with_namespace
}
}
Vendor\EXt\Domain\Model\Extended {
mapping {
tableName = fe_users
recordType = Tx_Extendfeuser_Extended
}
}
}
}
}
Thanks!!!
Works with TYPO3 7.6.X as well

Related

Storing custom application configurations on cumulocity

Is there a way to store custom application configurations on the Cumulocity backend through the c8y.sdk? I would like to store a JSON with configuration information specific to an application created using the the smart app toolkit.
You can save settings at the tenant by using c8ySettings,
BUT you have a limitation of 256 characters per value.
I'm struggling with the same problem of storing larger plugin configurations without any success.
I asked about this from cumulocity support and they said it is possible to store custom JSON under managedobjects because at the moment they dont support storing JSON to database otherwise.
So you will need "create" or "admin" rights to inventory to be able to create new managedobject. You can store values like this:
var userSettings = {
type: 'userDashboardSettings',
yourSetting: somesetting,
id: settingsId
};
c8yInventory.save(userSettings).then(function(){
//do something
});
then you can search this newly created managedobject like this:
c8yInventory.list({
type: 'userDashboardSettings',
owner: id,
pageSize: 2
}).then(function (settings) { //do something }
So this way I was for example able to save user specific settings.
To find user dashboard settings do GET to: https://yourdomain.com/inventory/managedObjects/?type=userDashboardSettings&owner=IDHERE
To Delete managedObject do DELETE to: https://yourdomain.com/inventory/managedObjects/IDHERE
To see all managedObjects do GET: https://yourdomain.com/inventory/managedObjects
Type and user are important, this is how you find the managedobject.

executing a sql code for creating a table and database in zend framework

I wrote a sql script and in it I created a table ;
Now I need to know ,how I can execute this script? (with which codes?)
And I have another question : where? where I must write this codes?(which folder in zend project?)
if it is possible for you please explain with an example.thanks
Creating tables in the database
Zend Framework is not supposed to be the one creating the tables, thus, my suggestion is to run those scripts in other environment.
The fastest one is, probably, the very own SQL shell, but you can use another software such as MySQLWorkbench if you are using MySQL.
Once the tables are created, the access to the tables is made this way:
Introduction
When you are using Zend Framework, you are making use of the MVC pattern. I suggest you to read what is that: Wikipedia MVC
If you read the Wikipedia link, you probably know now that the acess to the database is going to be made by the model.
Thus, if you followed the recommended project structure that Zend provides you will have a models folder under your application folder. There, you are supposed to implement the classes that will make access to the DB.
But well... you now know where to locate those classes but you will ask me: how? It's easy if you know where to search. ZF provides an abstract class called Zend_Db_Table_Abstract that has all the methods that will make your life easier talking about interaction with your database's tables. This is the class that your classes should implement.
Example
Let's suppose you've got a page in your website in which you want to show to the user a list of products of your local store. You have a table in your database called "products" in which you have all the useful information such us name, price and availability.
You will have a controller with an action called indexAction() or listAction() this action is prepared to send the data to your view and will look like:
class Store_ProductsController extends Zend_Controller_Action {
public function indexAction(){
//TODO: Get data from the DataBase into $products variable
$this->view->products = $products;
}
}
And your view file will that that products variable and do sutff with it.
But now comes the magic, you will have a class that will access to the database as I've said, it'll be like:
class Model_Store_Products extends Zend_Db_Table_Abstract{
protected $_name = 'products';
public function getAllProducts(){
$select = $this->$select()
->from(array('P'=>$this->_name),
array('id', 'name', 'price', availability));
$productsArray = $this->fetchAll($select);
return $productsArray;
}
}
And ta-da, you have your array of products ready to be used by the controller:
class Store_ProductsController extends Zend_Controller_Action {
public function indexAction(){
$model = new Model_Store_Products();
$products = $model->getAllProducts();
$this->view->products = $products;
}
}
It can be said that, since fetchAll is public function, and our select does basically nothing but set which columns do we want (it doesn't even have a where clause), in this case, it would be easier to call the fetchAll directly from the controller with no where and it will recover the whole table (all columns):
class Store_ProductsController extends Zend_Controller_Action {
public function indexAction(){
$model = new Model_Store_Products();
$products = $model->fetchAll();
$this->view->products = $products;
}
}
Thus, our function in the model is not even needed.
This is the basic information of how to access to the database using Zend Framework. Further information of how to create the Zend_Db_Table_Select object can be found here.
I hope this helps.

How to get all FAL File Objects which are referenced?

I'm trying to make a extbase extension for TYPO3 to get alle file objects with mimetype image/... which referenced by any content, plugin or fluid in typo3.
But i don't know which is the best way to get these data. How should i create a model in my extension and how should i create the correct repository?
If i create a custom query i'm not sure how to return a complete FAL Object which contains any data (like metadata) etc.
hope someone could help me to find the right way, and maybe has a example or something.
thanks a lot
You could do it like this, details are at the bottom:
Get all file references.
Go through them, retrieve the referenced file for each of them and retain only the ones where the field mime_type starts with image/.
There are two things you probably need to watch out for:
The field mime_type needs to be up to date. Check the FAL scheduler indexing task for that.
Performance. Depending on the number of files you have, it could be much faster to do this with a custom SQL statement which makes use of a JOIN. But you should only do that if performance is a problem.
How to get all file references:
First, build your own empty file reference class:
namespace Vendor/Extkey/Domain/Model;
class FileReference extends \TYPO3\CMS\Extbase\Domain\Model\FileReference {}
Make sure to configure it in your TypoScript to be serialized to the table sys_file_reference:
config.tx_extbase.persistence {
classes {
Vendor\Extkey\Domain\Model\FileReference {
mapping {
tableName = sys_file_reference
}
}
}
}
Add a repository for the references:
namespace Vendor/Extkey/Domain/Repository;
class FileReferenceRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
public function initializeObject() {
/** #var \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface */
$defaultQuerySettings = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\QuerySettingsInterface');
$defaultQuerySettings->setRespectStoragePage(FALSE);
$this->setDefaultQuerySettings($defaultQuerySettings);
}
}
The reference class can be empty, but the repository needs it to be there in order to work correctly. Make sure you add the default query settings to ignore the page id, so you get all non-hidden and non-deleted file references by calling $fileReferenceRepository->findAll().
How to check the MIME-type of each referenced file:
You can get the MIME-type of each reference by calling
$fileReference->getOriginalResource()->getMimeType()
This should automatically fetch the original file from storage and read its MIME-type.

typo3 extbase permissions in extensions

I have written one extension for making service order.
The issue I am facing here is,
There are FE users belong to three FE user groups namely "client", "Admin" and "Employee".
Here the client can make order and he should be able to see only his orders.
And the admin can see all orders done by different clients.
And the employee should be able to see only some clients orders.
Currently I made a order table with N:1 relation with FE user table. So every order should relate with any one client.
So in controller, I am checking the login user and using custom query in repository, I am accessing order related to loggedin client (FE user)
In file OrdersController.php
public function listAction() {
$orders = $this->ordersRepository->orderForLoginUsr();
$this->view->assign('orders', $orders);
}
In file OrdersRepository.php
public function orderForLoginUsr(){
$loggedInUserId = $GLOBALS ['TSFE']->fe_user->user['uid'];
$query = $this->createQuery();
$query->matching(
$query->equals('user', $loggedInUserId)
);
$query->setOrderings(array('crdate' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING));
return $query->execute();
}
But here my question is how to make admin user able to see all the orders done by all clients?
I have to write different template and action that calling function findAll() ?
$orders = $this->ordersRepository->findAll();
And how to set for usergroup Employee ?
Thanks in Advance
I think that the easiest way is to actually implement 3 actions with 3 different plugins, something like: listClientAction, listAdminAction and listEmployeeAction
In each of those action, you implement a method in your repository that fetch the right list of order with the good ordering:
orderForLoginClient(), orderForLoginEmployee(), orderForLoginAdmin()
What does the trick actually is that there will be 3 plugins on your page, one for each action. In each instance of your plugin, you set the access for the right be_group.
Don't forget to add the actions and plugin in the localconf and ext_table files.
I hope it will help!
Olivier
If your view is almost the same for client, admin, employee you should simply add a method like getOrderWithPermissionsForUser($currentUser);
In the method itself you should check for the usergroup and call different queries on your Repo.
If your view is different from usergroup to usergroup, you should use different templates with partials for the same parts.
If the data of the views is the same, just change the template for each usergroup in the action. If not use different actions.
Here is a helper method for easily changing your templatefile.
/**
* This method can change the used template file in an action method.
*
* #param string $templateName Something like "List" or "Foldername/Actionname".
* #param string $templateExtension Default is "html", but for other output types this may be changed as well.
* #param string $controllerName Optionally uses another subfolder of the Templates/ directory
* By default, the current controller name is used. Example value: "JobOffer"
* #param \TYPO3\CMS\Fluid\View\AbstractTemplateView $viewObject The view to set this template to. Default is $this->view
*/
protected function changeTemplateFile($templateName, $templateExtension = 'html', $controllerName = null, AbstractTemplateView $viewObject = null)
{
if (is_null($viewObject)) {
$viewObject = $this->view;
}
if (is_null($controllerName)) {
$controllerName = $this->getControllerContext()->getRequest()->getControllerName();
}
$templatePathAndFilename = $this->getTemplateRootpathForView($controllerName . '/' . $templateName . '.' . $templateExtension);
$viewObject->setTemplatePathAndFilename($templatePathAndFilename);
}

Drupal 6, Views 2: Is it possible to have a filter that only applies to registered users?

Is it possible to create a filter in a Drupal 6 View that is only applied for registered users?
For one filter I need I'm using the user vote (With fivestar and votingapi) to know if they user already voted this node or not, and when the user is annonymous, is working as if all the votes from all the annonymous users where from the same. This is why I need to add this filter, but ignore it in case the user is annonymous.
Thanks a lot in advance for the help!
If you're comfortable with php, download the Views PHP Filter module (http://drupal.org/project/viewsphpfilter). This module allows you to easily write your own custom filters for any view.
After downloading and enabling the module, create a new view and add a "Node: Node ID PHP handler" filter. Now you can add custom php code for any filter you want. Perhaps something like:
global $user;
$allowed = array('authenticated user');
foreach ($user->role as $role) {
if (in_array($role, $allowed)) {
$nids = //Run custom filter query for allowed users
}
else {
$nids = //Run alternate filter query for anonymous users
}
}
return $nids;
The code should return a list of node ids to display.