CakePHP3 Tree bahavior + translation behavior - php

Im trying to create a list of categories that need to be translated and display them as a tree structure. But so far no luck, i got tree structure going but when ever i create new category it adds up to the tree but wont display the name because its being translated with i18n and stores in diffirent table...
$categories_list = $this->Categories->find('treeList')->toArray();
This var stores tree it self with names that i have in Categories Table...
$categories_list = $this->Categories->find('translations')->toArray();
And this one gives me the actual translated categories, anyone has any idea how to combine them, CakePhp3 is a new thing for me and i cant find to much documentation about combining those two behaviors.

In order to get translated fields into tree list you need to add TranslateTrait into Category entity, it should look like this:
Link to CookBook about Translate behaviour and TranslateTrait
/src/Model/Entity/Category.php
<?php
namespace App\Model\Entity;
use Cake\ORM\Behavior\Translate\TranslateTrait;
use Cake\ORM\Entity;
class Category extends Entity{
use TranslateTrait;
//translation field must be accessible
protected $_accessible = [
'translations' => true,
];
}
Then you should stack multiple finder methods to achieve your goal, one for Translation Behaviour and one Tree Behaviour
Link to CookBook about how to stack multiple finder methods
/src/Controller/ArticlesController.php
use Cake\I18n\I18n;
public function foo(){
/***
*
* 1) use translation finder
* 2) use treeList finder
* 3) give to treeList finder the translated value to use in the output array as valuePath param
*
***/
$tree_list = $this->Articles->Categories
->find('translations')
->find('treeList', ['valuePath' => '_translations.' . I18n::getLocale() . '.title'])
->toArray();
}
You can leave I18n::getLocale() as it is to automatically get the tree list in current language or replace it with the language you prefer.

Related

Use one table for different resource in Laravel Nova

I'm trying to create something like a blogging system inside the Laravel Nova.
I have a table named articles as well as abstract model AbstractArctile.
I also have 3 categories:
News - App\Models\News\Article extending the App\Models\Abstract\AbstractArticle
Digests - App\Models\Digests\Article extending the App\Models\Abstract\AbstractArticle
Offtopic - App\Models\Offtopic\Article extending the App\Models\Abstract\AbstractArticle
The table articles has a field named category, and there are 3 types of categories: news, digests, offtopic.
Besides the extending the abstract model, each resource model also has one attribute defined, which is it's category in the following manner:
/**
* To which category this article belongs to
* #var array
*/
protected $attributes = [
'category' => 'news'
];
I have no problem creating the articles under the specified categories in the Nova, however, instead of showing the articles from specified category, it displays articles from all categories on all resources.
Is there a way to display articles only from certain category on a given resource?
Summary
One abstract model -> 3 resources extending that model (with category attribute defined) -> how to display only items from that category inside the nova resource?
You can make use of Laravel eloquent query scope.
Add global scope like below to all 3 models (App\Models\News\Article, App\Models\Digests\Article, App\Models\Offtopic\Article), which is a easy way to make sure every query for a given model receives category constrains.
protected static function boot()
{
parent::boot();
static::addGlobalScope('category', function (Builder $builder) {
$builder->where('category', 'news'); // Change the value depends on the model
});
}
Hope this will help you.
In Nova, you can use indexQuery,detailQuery and editQuery as well and customize your resource results.
https://nova.laravel.com/docs/4.0/resources/authorization.html#index-filtering

TYPO3: Extend model and map to existing table

I need to create a custom FE user with some custom fields.
Also, it needs to be assignable through the frontend to different user groups.
You can find my first approach here. Didn't work out that well.
Second approach was to create another extension and follow the guide which is shown here.
First thing I did was to add \TYPO3\CMS\Extbase\Domain\Model\FrontendUser into the Extend existing model class-field for my CustomFEU-model.
Then I created another model which I named FEgroup and I mapped it to the table fe_groups. After that, I connected an n:m relation to the CustomFEU.
When I try to create a new CustomFEU with the new action, it returns a white empty page after submitting the form and no user is being added.
The only strange thing I found was that the /Classes/Domain/Repository/ folder is empty.
TYPO3 7.6.8
Although I didn't edit the files yet, here they are:
Model / Controller / Setup
Did anyone encounter similar problems?
First you need to create the repositories that handle the new user and usergroup models.
Second you try to save the user with $this->customFEURepository->add($newCustomFEU); and the variable customFEURepository does not exist. It would be the best to inject it, it has to be the repository that you should create first. You can inject it like that:
/**
* CustomFEUController
*/
class CustomFEUController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
/**
* #var \Vendor\Feregistration\Repository\CustomFEURepository
* #inject
*/
protected $customFEURepository;
// other code ...
}
Don't forget to clear the system cache after adding inject annotations, otherwise it wont work.
Last but not least i can't see the mapping to the database table for your model. You need to add it to your TypoScript (setup.txt)
config.tx_extbase.persistence.classes {
Vendor\Feregistration\Domain\Model\CustomFEU {
mapping {
recordType = 0
tableName = fe_users
}
}
Vendor\Feregistration\Domain\Model\FEGroups {
mapping {
recordType = 0
tableName = fe_groups
}
}
}

Cakephp, display field = another foreign key

I have 3 models
MasterParts hasmany Parts
Parts hasmany PickLines
MasterPart.php:
public $displayField = 'mp_part_nr';
Part.php:
Parts display field is another foreign key:
public $displayField = 'master_part_id';
In Picklines I have a dropdown for partnr's referencing the available parts, so I need to show a grouped list of all the partnr.'s of the Parts table.
Unfortunately is shows a list of id's. (note: I created the models, controllers and views using cake bake.)
I would imagine Cake would link the functionality so I do not need to write something like:
public $displayField = 'MasterPart.mp_part_nr';
(which doesn't work anyways)
How can I get a list of partnr's instead of id's?
Figured it out myself, I just need to change the code in my PickLinesController by adding the MasterParts class:
$parts = $this->PickLine->Part->MasterPart->find('list');

Storing a document in a different collection - Mongodb with symfony2

Im trying to store a document in a different collection by using Mongodb and symfony2
This is my controller who sets the document into the db.
public function createAction(){
$post = new Post();
$post->setUrl('A Foo Bar');
$post->setTitle('asdf');
$dm = $this->get('doctrine.odm.mongodb.document_manager');
$dm->persist($post);
$dm->flush();
return new Response('Created post id '.$post->getId());}
As you can see, this is the example for the official documentation on DoctrineMongoDBBundle
But the problem is that by default it creates the document into a Collection named as the class, in my case is Post(), so the collection name is Post. I will like to save the document into a Collection named for example charlies_posts or any string as a variable.
It's easy :) In the definition of your document class just use the "collection" parameter.
Here is an exemple :
<?php
namespace MyProject\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
/**
* #ODM\Document(
* collection="charlies_posts"
* )
*/
class Post
{
Yeahp, as you say we can define that as a parameter.
Documents\User:
type: document
db: my_db
collection: charlies_post
In this case in the YAML mapping file a different collection may be selected but in my case i want to dinamically set the collection name because i have post related to the user so charlies posts should go to the charlies_post collection and peter posts should go to peter_post collection...
I suppose that there must be a method to set this but i cant find it..

Ordered dropDownList using relations?

I have some forms in Yii using the following to get lists of data from related tables in the form of a drop down:
dropDownList(CHtml::listData(Company::model()->findAll(array('order' => 'company ASC'))));
This works, but that means for every drop down list (which theres a lot of) I'm putting this array('order' => 'company ASC' in every one.
Is this the best way to do it? Is there not a way to get this data using the model relations(), and specifying the order within the relation?
I believe that the correct way to do this is by using scopes.
You can define any number of scopes that order the result set and use them like so:
Company::model()->scopeName()->findAll();
If your application always requires companies to be fetched in a sorted order, you can even define a default scope in your model class:
public function defaultScope() {
return array('order' => 'company ASC');
}
This will result in every call to Company::model()->findAll(); returning sorted results.
I usually add an opts() methods to each model that could be used as source for a dropdown:
class Company extends CActiveRecord
{
// ...
public static opts()
{
$opts = array();
foreach(self::model()->findAll(array('order'=>'name ASC')) as $model)
$opts[$model->id] = $model->name;
return $opts;
}
It's used like this
echo $form->dropDownList($user, 'company_id', Company::opts());
If you need the same options several times on a page, you could even "cache" the result in a private static class variable or use DAO to fetch the list data in a more efficient way.

Categories