Symfony World blog is not maintained anymore. Check new sys.exit() programming blog.
Showing posts with label plugins. Show all posts
Showing posts with label plugins. Show all posts

doctrine act as signable plugin - new releases

After few months, new versions 1.2.2 and 1.2.3 of sfDoctrineActAsSignablePlugin have been released. In short, the plugin provides a Signable behavior which automatically stores information on who has created or updated a given object.


what's new

A fellow symfony developer, Daniel Möllenbeck, suggested that there are some options missing in the behavior configuration. Until version 1.2.1, the onDelete option was hardcoded as CASCADE, which - as Daniel emphasised - may cause problems when a given user is supposed to be deleted (physically from the database, not softDeleted).


ALTER TABLE customer
ADD CONSTRAINT customer_created_by_sf_guard_user_id
FOREIGN KEY (created_by)
REFERENCES sf_guard_user(id)
ON DELETE CASCADE;

ALTER TABLE customer
ADD CONSTRAINT customer_updated_by_sf_guard_user_id
FOREIGN KEY (updated_by)
REFERENCES sf_guard_user(id)
ON DELETE CASCADE;

Let's imagine user enters customers over and over, then leaves the company. Now the admin deletes the user - probably the hard way (directly on the database, maybe the user is auto-created from somewhere...) --> The constraint will trigger the deletion of all customers created by that user. I have some doubt anybody would be happy about that.

Having the constraint like that does the trick:

a) allow NULL values in created_by/updated_by columns:

ALTER TABLE customer
ADD CONSTRAINT customer_created_by_sf_guard_user_id
FOREIGN KEY (created_by)
REFERENCES sf_guard_user(id)
ON DELETE SET NULL;

ALTER TABLE customer
ADD CONSTRAINT customer_updated_by_sf_guard_user_id
FOREIGN KEY (updated_by)
REFERENCES sf_guard_user(id)
ON DELETE SET NULL;

b) forbid the deletion of the user:

ALTER TABLE customer
ADD CONSTRAINT customer_created_by_sf_guard_user_id
FOREIGN KEY (created_by)
REFERENCES sf_guard_user(id)
ON DELETE RESTRICT;

ALTER TABLE customer
ADD CONSTRAINT customer_updated_by_sf_guard_user_id
FOREIGN KEY (updated_by)
REFERENCES sf_guard_user(id)
ON DELETE RESTRICT;

c) do nothing

moreover


Another fellow symfony developer, Christoph Berg, helped me to trace the bug with fixtures on created_by/updated_by values. Now, the bug is fixed and all fixture data works perfectly.


the community


Taking the opportunity, I'd like to thank Daniel, Christoph and all other symfony developers who share their opinions on my work - they help to find bugs and suggest some good ideas on how to improve the code. Thanks to you, the plugin gets better and better all the time. Thanks, guys!


Please, feel free to share your opinion and comment on the plugin!

symfony sfAdminDashPlugin icons

sfAdminDashPlugin is one of the most useful symfony plugins (it's the 8th most popular plugin at the moment). I want to show few ways how to easily extend your backend application with custom icons: where to get them from and how to make your project use them. It seems not very complicated - and it's not :)! But the way your website looks like is still very important.



sfAdminDashPlugin built-in login screen

sfAdminDashPlugin is provided with some standard icons, but probably you'll need more of them. Especially that it's really easy to add new ones - just follow these steps:

  • find icon(s) that have the folowing sizes: 16x16 and 48x48, should be in .png format and be transparent in the background
  • copy those files to the plugin directories: PROJECT/plugins/sfAdminDashPlugin/web/images/icons - for the 48x48 file and PROJECT/plugins/sfAdminDashPlugin/web/images/icons/small for the 16x16 file
  • use new icon(s) in your config/app.yml configuration file:
    items:
      Articles:
        url:          article
        image:        CustomIcon.png
    



set of icons provided with sfAdminDashPlugin

desktop environment

The easiest place to look for your icons is your desktop environment resources directory. For example, I use KDE which stores its icons in

/usr/share/icons/
/usr/share/icons/default.kde4/16x16
/usr/share/icons/default.kde4/48x48


external resources

KDE has lots of icons added by users, which you can find here. I have downloaded several packages and whenever I need a specific icon, I look through them. Good thing about icon themes is that large amount of icons are created in the same style, which would make your backend look even better!



nuvola KDE icon theme

Of course, you may also find nice icons at special websites, such as

and many more (these two I use the most - to see the rest, ask google)...



icon usage example


drop-down menu example


icon usage example


drop-down menu example


icon usage example

update record changes with sfDoctrineActAsSignablePlugin: Signable behavior

sfDoctrineActAsSignablePlugin


The plugin is fairly simple, it contains only a Doctrine temlate and a template event listener (basic stuff to implement a new Doctrine Behavior). It was initially released by Vitaliy Tverdokhlib.


Signable Doctrine Behavior


The plugin provides a Signable behavior ready to be used in your models:

Model:
  actAs:
    Signable: ~
It works very similarly to Timestampable behavior: created_at and updated_at timestamp columns are added, storing information about the datetime that a record was created and last updated. Signable adds created_by and updated_by columns storing information about the user that created or last updated a record.


The plugin may be used along with sfDoctrineGuardPlugin. This gives you a possibility to refer to the sf_guard_user table. No additional configuration is needed, the plugin automatically checks if sfDoctrineGuardPlugin is installed.


configuration


The most important thing you can configure is to choose the type of the user field: it can be either string or integer:

Model:
  actAs:
    Signable:
      created:
        type: string
      updated:
        type: integer
If string type is chosen, you can simply display the name of the user (e.g. in frontend blog article display page), but can do nothing further. If you choose integer, you store ID of the user, which gives you a possibility to refer to the user in the user database table (which gives you all possibilities of using user Doctrine model).


You can configure the behavior to meet your needs. Let's take a look at some examples:


  • The created_by and updated_by column names are the default ones. You may change them:
    Model:
      actAs:
        Signable:
          created:
            name: creator_id
            type: integer
          updated:
            name: update_username
            type: string
    

  • You want to know which user has created a record only (meaning that the user who updated the record is not important). In this case, disable udpated option:
    Model:
      actAs:
        Signable:
          updated:
            disabled: true
    

  • You want to add the Signable behavior to models of an existing project that already maintaines lots of data. And you want the created_by/updated_by user to be not null, because there's always someone who creates or updates a record. In a big project (a CRM, ERP, etc.) it's a good solution to create a system user (with id=1 for example) who represents all system actions (a daemon creating/updating objects from cron tasks):
    Model:
      actAs:
        Signable:
          created:
            options:
              notnull: true
              default: 1
          updated:
            options:
              notnull: true
              default: 1
    
    In this case, adding created_by/updated_by database columns will fill them initially with 1 (system user) and you can refer to the user (e.g. using getUser() method), being sure that there's always a user referenced. And all further modifications will store real user ids.


real world examples



  • Blog articles are being added by application users. You add Signable behavior (with type: string) and you may use:
    echo $article->getCreatedBy();
    in the app frontend to display who submitted the article.

  • An E-commerce applications management system: users (employees) log in to the system and create orders that customers submit. You add Signable behavior (with type: integer). Whenever an order is created, the created_by is filled with the user ID. The application can generate statistics on which users added the most orders.


No matter if your project is a complex management system with extended backend - or a small company website with mainly frontend developed - you'll find this plugin useful!

new releases of sfApplicationMapPlugin

application map

sfApplicationMapPlugin is an easily configurable documentation-generator tool. It generates a graphical map of your applications using GraphViz software. It is useful when you want to have an overwiev of a specific application or of a whole project - each module/admin-module is marked with all actions and their comments. Take a look at the plugin readme tab to see some examples. You need to have GraphViz installed on your system to use the plugin.




new release

New plugin versions supporting symfony 1.2-1.4 has been released. Thanks to bugs reported by Gordon Bazeley, the plugin should work correctly with no dependency on operating system.




an official GraphViz-based software

sfApplicationMapPlugin is listed as a Software Engineering Tool on the official Graphviz website.


todo and contribution

The main thing to be done is supporting plugins used in projects. Any contribution is welcome, as well as bug reports and questions.

Embedding videos in symfony projects using sfVideoPlugin

What does the plugin do?


sfVideoPlugin is a plugin created by a small international symfony developers team. It's destined to give an easy interface for online video embedding. The plugin uses flowplayer software and uses files with the flv extension.

It's so easy


sfVideoPlugin comes provided with few ways of embedding a flash video player inside you project.

including a partial

Once the plugin:publish-assets task has been run, flv files can be accessed from the web. Just include the video partial from the sfVideo module (enable it first, of course) passing one obligatory parameter - file (it's taken from the default flv directory):

include_partial('sfVideo/video', array('file' => '01.flv'));
Take a look at the plugin demo site.


video widget

Use the sfVideoWidget class inside your forms to display the player inside a form (you may use predefined sfVideoForm class which has only one widget). An example study case using video widget is uploading video files in the backend - user should have the opportunity to display the video file before publishing it online.


multiple player embedding

A simple parameter has been added to the partial mentioned above to enable displaying more than one video widget on one page. If the player parameter is not set when including a partial, the default value is "player" - you need to override the default value to display more than one player. Put the following code into an action:

$this->players = array(
  array('file' => '01.flv', 'player' => 'player01'),
  array('file' => '02.flv', 'player' => 'player02'),
  array('file' => '03.flv', 'player' => 'player03'),
);
and include the partial for each of defined players:
<?php foreach($players as $p): ?>
<?php include_partial('sfVideo/video', $p) ?>
<?php endforeach; ?>
Take a look at a live demo.


configuration

At now, there are four attributes defined in the app.yml file that are common for all players in the plugin. These are:

  • width
  • height
  • autoplay
  • autobuffering
The first two attributes take an integer value and the rest takes true/false values. Access them using:
sfConfig::get('app_video_autoplay')


contribution

Feel free to comment on the post and to contribute to develop the plugin.

symfony development plugins

Symfony framework comes bundled with many great plugins, they can be extremely useful for your projects' functionalities. But there are very few plugins that provide documentation functionalities. While developing a big project, it's really easy to get messed up with working on dozens of model classes, modules, actions, etc.

There are few plugins I would like to recommend:
  1. sfDoxygenPlugin
  2. sfApplicationMapPlugin
  3. sfDoctrineGraphvizPlugin
Each of them performs different tasks, each of them may be found very useful while designing and developing your sites.

sfDoxygenPlugin

This plugin is an alternative to sfPhpDocPlugin. Doxygen seems to be the best cross-platform documentation tool available, including lots of configuration features (one of them is easy UTF-8 rendering, in comparison to phpDocumentor which still lacks support for any encoding different than ISO-8859-1).

You only need to have doxygen installed, execute few tasks, modify the configuration and your code documentation is ready. Remember that a developer has to go back to the application code even few years after finishing a project. If no documentation is found then, applying even small changes is... quite difficult.

sfApplicationMapPlugin

The last two plugins are based on GraphViz, a wonderful graph rendering tool. The plugin is provided with only one task and is easier to use than sfDoxygenPlugin. After installing you only need to run one task and the application map is already generated.

What is this application map? It's a graph in which each element of the controller has it's own node. That is, the project-root node has child apllication nodes (e. g. backend, frontend), application nodes have child module nodes (including both admin generators and custom modules) and, finally, module nodes have child action nodes. Each node is labeled with the name of the project, application, module or action, depending on the node type. Each action is additionally provided with the documentation code. All this makes sfApplicationMapPlugin a very useful tool when you want to take a brief look at you application and you don't like browsing lots of files - the plugin does it for you and generates nice images. Take a look at the plugin readme to see example application maps(#1, #2).

sfDoctrineGraphvizPlugin

Finally, database schema has to be documented as well. Many developers tend to use good old FabForce's DBDesigner 4. But, as it usually happens, many tiny differences are made during development, time is money and updating your DBDesigner schema is definitely NOT money, therefore the schema image is not up-to-date...

Why using DBDesigner and spending your time on updating a file which won't be used in your project, when all the database schema information you need is present in schema.yml files? This is where the sfDoctrineGraphvizPlugin comes to help. Just like sfApplicationMapPlugin - just install, run one task and the images are generated for you.

Conclusion

During site development, a developer usually doesn't care about documenting the project. But if he leaves it for a long time, or when a new developer comes to replace him, understanding of a project becomes a big problem. Don't forget to provide a good value documentation for you projects, it takes very little time - and eventually saves a lot of it.