symfony dynamically add translation based on condition - symfony

I'm searching for a way to add a translation to an existing translation catalogue during runtime.
I have a working symfony 2.3 application which uses translations in de/en/fr/it and fetches all available translation keys from /Resources/translations/messages..yml.
Now if a user logs in I want to have the possibility to override some of the already loaded labels based on setting for that user (e.g. textfield in DB which holds key-value-pairs).
E.g.
messages.en.yml
company.name.short: Company profile
Usersetting:
company.name.short: Profile for company
I found no way to add/override keys to the existing catalogue or to make them available in twig. Is there a Bundle or a setting or some Symfony magic to get this to work?

You'll probably want to extend Symfony's own translation class for this. This article explains how to do that:
http://www.webtipblog.com/extend-symfony-2-translator-to-log-untranslated-messages-to-a-database/
The key point is to override the "translator.class" parameter in your config, and then point it to your own class that first checks for database overrules and will defer to the symfony default implementation if it cannot find one.

Related

Defining default #GeneratedValue Strategy for Symfony MakerBundle

When using the MakerBundle in Symfony (4) to create new entity (make:entity EntityName), an id is generated by default with annotation (if annotations enabled) #GeneratedValue.
#GeneratedValue means #GeneratedValue(strategy="AUTO").
According to the Doctrine documentation, the AUTO strategy is supposed to use SERIAL type for the id in PostgreSQL. But, I do not know why in my case, the AUTO strategy use SEQUENCE for the id.
Then, I can force it to use SERIAL by changing by hand into #GeneratedValue(strategy="IDENTITY") which means using SERIAL type in PostgreSQL.
Is there any way to change the default #GeneratedValue annotation created by the MakerBundle for the new entities to be created with the #GeneratedValue(strategy="IDENTITY") annotation ?
What you could possibly do is decorate \Symfony\Bundle\MakerBundle\Doctrine\EntityClassGenerator which is registered as a service named maker.entity_class_generator in vendor/symfony/maker-bundle/src/Resources/config/services.xml and override its generateEntityClass method to make a different call on the Generator's generateClass method, specifically the file path could be changed there.
Seems like the file path there could be relative or absolute, so with some trial and error you could get it to output the annotation you want. The template that the maker bundle uses now is at vendor/symfony/maker-bundle/src/Resources/skeleton/doctrine/Entity.tpl.php, and it's pretty straightforward to modify.

Keep two different versions of an entity in Doctrine ORM

I'm working on a Symfony4/Doctrine/MySQL project with the following requirement:
Users can create entities (say posts) that are visible in the public frontend only after approval by an admin
When a user edits his post after approval/publication, the changed post needs to be approved again before the changes will become visible in the frontend. But while approval is pending the old approved version of the post must remain visible in the frontend.
This means I have to keep two versions of every "Post" entity: the approved version for the frontend and the work-in-progress version for the backend.
In past projects with similar requirements I tried different approaches to this problem:
Using "Versionable behavior" (this was in the Symfony1/Propel days using sfPropelVersionableBehaviorPlugin). For display in the frontend, if an entity was not approved I had to fetch the previous versions until the latest approved version was found.
Using a second entity/database table "ApprovedPost" with the same field definition as the main "Post" entity. When a post is approved by the admin, it will be copied to the ApprovedPost table. The frontend operates on the ApprovedPost table only.
What is the current best practice to implement such a behavior?
Because I am chellenging this problem right now, I want to share my approach.
The entity is a request for something. Everytime something changes, the changes should be preserved.
The approach:
On every edit action, a new entity row is created.
The entity has an "approved" flag and a createdAt Date field.
A request has a nullable one-to-one self relation (to point to the root/parent entity).
A custom repository is used fo accessing the database.
The typical find and findAll methods are modified: they search for the most recent version (by the createdAt field) that is approved.
Search is done via custom SQL/DQL: (WHERE id = ?1 OR WHERE parent-id = ?1) AND WHERE approved = true SORT BY created_at DESC LIMIT 1
More features can be added like enabled/disabled, deletion and so on ...
If you want to render the page server side and show the changed or old versions, I would recommend writing e.g. a Twig extension. You could implement different search functions in the repo and handle the representaion via the extension (sorting, referencing ...).
I created an API, which is able to do both: return the newest version and return all versions (with or without root or newest), but I use the latter one in the frontend only if necessary.
Like dbrumann stated, this is a opinionated approach (I like custom repos, because I can create them type safe and I can decouple application from persistence logic).

How to make RSS Feed Generator for ASRP Blog Posts in AEM 6.2

Am looking for generate RSS feed from ASRP blog Posts from AEM to Integrate in Third Party Plugin,
does AEM have any OOTB solution for this ?
or we need to create a custom RSS feed generator ?
any help would be appreciated.
Thanks
As per the Adobe Forum Thread, RSS OOTB feature is currently unavailable for AEM 6.1/ 6.2 Communities. So, you can create custom polling importer and do your stuff.
To create custom importer:
You need to define two properties in your importer class:
You can write your custom code in the overridden method.
When this service is deployed in AEM instance, your custom importer can be seen in the dropdown of the polling configuration.
Polling configuration has a dialog, which you need to fill while creating your polling nodes. The below diagram shows how values given in config dialog mapped to node properties and then to importData() method:
The importData() method of custom importer gets the value of its parameter from this configuration. Thus you need to specify these properties in the dialog:
Type: It defines feedType property of poll config node.
URL: It defines feedUrl property. This mandatory field defines the source( or xml) to read.
Import to path: It is the path where nodes needs to be created. It defines target property. This path is resolved to a resource and is passed in importData(). If target value is not provided, path of the configuration node is resolved.
Update Interval in Seconds: It tells after how many seconds it needs to poll. Its default value is 1800 and minimum value is 300. It defines interval property of pollConfig node.
There is one more property in pollConfig node i.e. source which is concatenation of
<feedType>:<feedUrl>
After poling nodes are created, it will fetch your feeds from the given URL and store it in the targetted path.

Silverstripe's Versioned feature for dataobjects in new release (3.2)

I want to audit-trail all changes made to dataobjects. Say I have Event dataobject and I want to know who changed it, when changed, what is changed etc. (Similar to Pages).
Silverstripe site recommends the use of Verioned but I can't find any examples of implementation. It says the best example is Pages which is is already comes with Versioned implemented. The basic rule is to define an augmentDatabase() method on your decorator.
So, I want to use DataExtention for dataobject (extension) and then use the extended one for my Event dataobject. But is there any simple example?
Assuming you want to manage and monitor multiple versions of the event DataObject, you simply need to declare that you want to use the versioned extension for thatDataObject
Class Event extends DataObject{
static $extensions = array(
"Versioned('Stage', 'Live')"
);
...
}
Then run a dev/build
You should now have a Event, Event_Live, and Event_versions tables.
You can then have a look at the methods available in Versioned.php, and use them with Event, ie publish(). This should get you started.
"Versioning in SilverStripe is handled through the Versioned class. It's a DataExtension, which allow it to be applied to any DataObject subclass."
"Similarly, any subclass you create on top of a versioned base will trigger the creation of additional tables, which are automatically joined as required."
Here is link to read further with examples
Versioning of Database Content

Use FOSUserBundle in relation with yml-based Entities

I've started a Symfony2 project from scratch where I then installed FOSUserBundle.
Then, I have written (actually, generated with ORM Designer) some entities that need to have relations between them, and with the User entity.
I have Items belonging to Users, Collections belonging to Users that group Items, and so on.
Since I used FOSUserBundle I only have a basic User class (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md , step 3a) defined using annotations, no config/doctrine folder and no User.yml file in it.
I then created the MyBundle/Resources/config/doctrine folder and added the yml files mentioned above.
When I try to generate the entities with the command-line tool everything works fine: it will create the Entities from my yml files.
However, at this point, trying to load up in browsers the url where the login previously worked (when I only had the FOSUserBundle installed) will throw this error:
MappingException: No mapping file found named
'/var/www/concert/src/X/MyBundle/Resources/config/doctrine/User.orm.yml'
for class 'X\MyBundle\Entity\User'.
Following actions, such as generating the CRUD logic, will not work as long as I have an *.orm.yml file in the config/doctrine folder. If I remove those, CRUD generation will work, but generation of actual mysql tables won't.
Juggling with these gets me to a point where I can also get the tables, but then the actual app doesn't work if I try to use any of the url's where the newly generated CRUD is involved because since the entities are based on yml (which I remove to get things "working") it won't have any mapping knowledge.
Is this inherently wrong? To have yml-based entities in relationship with an User entity based on the FOSUserBundle and still be able to get the nice command-line generation tools?
The problem you describe stems from mixing configuration formats (yaml and I assume annotations). You can easily fix this by ditching the annotations in your models and replacing them with yaml-files like you would do in your own models.
Unfortunately the FOSUserBundle-docs only show you how to use annotations, so here is a quick transformation into yaml format when your X\MyBundle\Entity\User extends FOSUSerBundle's UserEntity:
X\MyBundle\Entity\User:
type: entity
table: fos_user
id:
id:
type: integer
strategy: { generator: "AUTO" }
The remaining stuff is taken care of by FOSUserBundle, as the BaseModel is a mapped-superclass and already describes the stuff in the User.orm.xml, but you could just as well replace the existing values or add additional values just like you would do with your own models.
If you don't use annotations throughout your app, you might also want to disable them in your app/config/config.yml to prevent side effects.

Resources