NANO-FRAMEWORK.COM

Framework PHP Objet UML

Navigation
HOWTO
Boîte à outils
Outils personnels
Action :

Exemple

Sommaire

Analyse du besoin applicatif

Afin de permettre une bonne approche du framework nano, nous partirons d'un exemple assez simple : la création d'un site de type "blog".

Ce site servira à la publication de nouvelles (News) ou d'article. Ces deux entités pourrons entre être commentées par des visiteurs non connectés.

Les news et articles seront déposé par des utilisateurs connectés.

Les news et articles pourront être classés par des "tags".

Nous identifierons donc les classes participantes suivantes :

Le modèle de classes

Définition du modèle : le schéma

Image:class_diagram_nano.gif

Définition du modèle : le fichier yml

Nous pouvons aisément déduire de notre exemple, le diagramme de classes participantes :


Nous pouvons désormais transcrire ce modèle de classes dans un fichier YAML qui va nous permettre de générer les classes PHP nécessaires à la manipulation de nos objets :

/configuration/schemas/schema001.yml (001 correspondant à la version du modèle)

  1. class :
  2. Comment :
  3. attributes :
  4. body :
  5. type : text
  6. published :
  7. type : boolean
  8. constraints :
  9. created_by :
  10. foreignClass : Person
  11. localAlias : created_by
  12. foreignAlias : comments
  13. type : has_one
  14. taggable_content :
  15. foreignClass : TaggableContent
  16. localAlias : taggable_content
  17. foreignAlias : comments
  18. type : has_one
  19. access : final
  20. User :
  21. extends : Person
  22. attributes :
  23. login :
  24. type : varchar(255)
  25. password :
  26. type : varchar(255)
  27. checked :
  28. type : boolean
  29. access : final
  30. TaggableContent :
  31. attributes :
  32. title :
  33. type : varchar(255)
  34. i18n : true
  35. extract :
  36. type : text
  37. i18n : true
  38. body :
  39. type : text
  40. i18n : true
  41. created_at :
  42. type : timestamp
  43. updated_at :
  44. type : timestamp
  45. published :
  46. type : boolean
  47. constraints :
  48. created_by :
  49. foreignClass : User
  50. localAlias : created_by
  51. foreignAlias : taggable_contents
  52. type : has_one
  53. access : abstract
  54. Article :
  55. extends : TaggableContent
  56. access : final
  57. News :
  58. extends : TaggableContent
  59. access : final
  60. Tag :
  61. attributes :
  62. label :
  63. type : varchar(255)
  64. constraints :
  65. taggable_content_tag:
  66. foreignClass : TaggableContent
  67. localAlias : taggable_contents
  68. foreignAlias : tags
  69. type : has_and_belong_to_many
  70. access : final
  71. Person :
  72. attributes :
  73. first_name :
  74. type : varchar(255)
  75. last_name :
  76. type : varchar(255)
  77. email :
  78. type : varchar(255)
  79. web_site :
  80. type : varchar(255)
  81.  

Génération des modèles

Une fois notre modéle de classe décrit dans le fichier YAML, il est trés simple de générer toutes les couches du modèle via la commande script/nano generate-models. Nous obtenons en sortie :

 
jean-philippe@jean-philippe-laptop:~/www/open-solutions$ script/nano generate-models
loading Tag
loading Person
loading User
loading TaggableContent
loading Article
loading News
loading Comment
------------------------------------------------------------
------------ generating yml class file ---------------------
------------------------------------------------------------
/home/jean-philippe/www/open-solutions/configuration/../configuration/schemas/schema001.class.yml written
------------------------------------------------------------
------------ generating class model layer ------------------
------------------------------------------------------------
/home/jean-philippe/www/open-solutions/configuration/../models/class/Tag.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/class/Person.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/class/User.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/class/TaggableContent.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/class/Article.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/class/News.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/class/Comment.php written 
 
------------------------------------------------------------
------------ generating orm model layer ------------------
------------------------------------------------------------
 
/
/home/jean-philippe/www/open-solutions/configuration/../models/class/Tag.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/class/Person.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/class/User.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/class/TaggableContent.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/class/Article.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/class/News.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/class/Comment.php written 
------------------------------------------------------------
------------ generating yml mpd file -----------------------
------------------------------------------------------------
/home/jean-philippe/www/open-solutions/configuration/../configuration/schemas/schema001.mpd.yml written
------------------------------------------------------------
------------ generating mpd model layer --------------------
------------------------------------------------------------
/home/jean-philippe/www/open-solutions/configuration/../models/mpd/Tag.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/mpd/Person.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/mpd/User.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/mpd/TaggableContent.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/mpd/TaggableContentI18n.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/mpd/Article.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/mpd/News.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/mpd/Comment.php written 
/home/jean-philippe/www/open-solutions/configuration/../models/mpd/TaggableContentTag.php written 
/home/jean-philippe/www/open-solutions/configuration/../configuration/schemas/class.map.yml written
written 
 

Le modèle de données

Une fois le modèle de classe généré, il faut générer le modèle de données pour permettre l'abstraction.

Generation du SQL de création

Afin de créer toutes les tables necessaires, nous utiliserons la commande : script/nano build-sql Nous obtenons en sortie :

 
SET AUTOCOMMIT=0;
SET FOREIGN_KEY_CHECKS=0;
CREATE DATABASE IF NOT EXISTS opensolutions;
 
DROP TABLE IF EXISTS `tag`;
 
CREATE TABLE `tag` (
`id` integer auto_increment not null,
`label` varchar(255),
CONSTRAINT PRIMARY KEY (`id`)
) Type = InnoDB;
 
 
DROP TABLE IF EXISTS `person`;
 
CREATE TABLE `person` (
`id` integer auto_increment not null,
`first_name` varchar(255),
`last_name` varchar(255),
`email` varchar(255),
`web_site` varchar(255),
CONSTRAINT PRIMARY KEY (`id`)
) Type = InnoDB;
 
 
DROP TABLE IF EXISTS `user`;
 
CREATE TABLE `user` (
`id` integer auto_increment not null,
`login` varchar(255),
`password` varchar(255),
`checked` boolean,
`person_id` integer,
CONSTRAINT PRIMARY KEY (`id`)
) Type = InnoDB;
ALTER TABLE `user` ADD CONSTRAINT FOREIGN KEY (`person_id`) REFERENCES `person`(`id`) on delete cascade;
 
 
DROP TABLE IF EXISTS `taggable_content`;
 
CREATE TABLE `taggable_content` (
`id` integer auto_increment not null,
`created_at` timestamp,
`updated_at` timestamp,
`published` boolean,
`user_id` integer,
CONSTRAINT PRIMARY KEY (`id`)
) Type = InnoDB;
ALTER TABLE `taggable_content` ADD CONSTRAINT FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ;
 
 
DROP TABLE IF EXISTS `taggable_content_i18n`;
 
CREATE TABLE `taggable_content_i18n` (
`id` int auto_increment,
`culture` varchar(8),
`taggable_content_id` integer,
`title` varchar(255),
`extract` text,
`body` text,
CONSTRAINT PRIMARY KEY (`id`,`taggable_content_id`)
) Type = InnoDB;
ALTER TABLE `taggable_content_i18n` ADD CONSTRAINT FOREIGN KEY (`taggable_content_id`) REFERENCES `taggable_content`(`id`) on delete cascade;
 
 
DROP TABLE IF EXISTS `article`;
 
CREATE TABLE `article` (
`id` integer auto_increment not null,
`taggable_content_id` integer,
CONSTRAINT PRIMARY KEY (`id`)
) Type = InnoDB;
ALTER TABLE `article` ADD CONSTRAINT FOREIGN KEY (`taggable_content_id`) REFERENCES `taggable_content`(`id`) on delete cascade;
 
 
DROP TABLE IF EXISTS `news`;
 
CREATE TABLE `news` (
`id` integer auto_increment not null,
`taggable_content_id` integer,
CONSTRAINT PRIMARY KEY (`id`)
) Type = InnoDB;
ALTER TABLE `news` ADD CONSTRAINT FOREIGN KEY (`taggable_content_id`) REFERENCES `taggable_content`(`id`) on delete cascade;
 
 
DROP TABLE IF EXISTS `comment`;
 
CREATE TABLE `comment` (
`id` integer auto_increment not null,
`body` text,
`published` boolean,
`person_id` integer,
`taggable_content_id` integer,
CONSTRAINT PRIMARY KEY (`id`)
) Type = InnoDB;
ALTER TABLE `comment` ADD CONSTRAINT FOREIGN KEY (`person_id`) REFERENCES `person`(`id`) ;
ALTER TABLE `comment` ADD CONSTRAINT FOREIGN KEY (`taggable_content_id`) REFERENCES `taggable_content`(`id`) ;
 
 
DROP TABLE IF EXISTS `taggable_content_tag`;
 
CREATE TABLE `taggable_content_tag` (
`id` integer auto_increment,
`tag_id` integer,
`taggable_content_id` integer,
CONSTRAINT PRIMARY KEY (`id`)
) Type = InnoDB;
ALTER TABLE `taggable_content_tag` ADD CONSTRAINT FOREIGN KEY (`tag_id`) REFERENCES `tag`(`id`) on delete cascade;
ALTER TABLE `taggable_content_tag` ADD CONSTRAINT FOREIGN KEY (`taggable_content_id`) REFERENCES `taggable_content`(`id`) on delete cascade;
 
 
SET FOREIGN_KEY_CHECKS=1;
 
 

Generation de la base de données

Pour générer la base de données, il suffit d'exécuter la commande : script/nano build-base

on obtient :

 
jean-philippe@jean-philippe-laptop:~/www/open-solutions$ script/nano build-base
Generating sql file... Ok
Loading sql file... Ok
 

Manipulation des objets

Une fois notre modèle et la base de données générés, on peut commencer à manipuler nos objects.

Les méthodes delete() et save()

Pour rentrer dans le vif du sujet, nous allons créer un premier objet User et le sauvegarder en base de données.

 
//instanciation de l'objet
$user=new User();
//attribution des valeurs
$user->first_name='Bart';
$user->last_name='Simpson';
$user->login='bart';
$user->pass=md5('my_pass');
//sauvegarde de l'objet
$user->save();
//suppression de l'objet
$user->delete();
 

On peut noter que nous ne manipulons que la classe finale User, les données étant elles sauvegardées sur les tables person et user (héritage).

Les finders

Les finders sont des méthodes permettant de récuperer des objets sauvegardés précédement.

 
//instanciation de l'objet
$user=new User();
//récupération de l'objet User d'id 1
$user=$user->find_by_id(1);
 

La méthode find_by_id($id) renvoi un objet.

 
//finder par attribut de classe
$user=$user->find_by_first_name('Bart');
//finder par object : find_by_local_alias($object)
$comment=new Comment();
$comment->find_by_id(1);
$user=$user->find_by_comments($comment);
 

Les autres finders renvoient des collection d'objets.

La methode add_local_alias()

Dans le cas d'une relation n.....n, on peut lier des objects via la methode add_local_alias($object).

 
$tag=new Tag();
$tag->label="Php";
$tag->save();
$article=new Artcile();
$article=$article->find_by_id(1);
$article->add_tags($tag);
 

La methode remove_local_alias()

Dans le cas d'une relation n.....n, on peut délier des objects via la methode remove_local_alias($object).

 
$tag=new Tag();
$tag->label="Php";
$tag->save();
$article=new Artcile();
$article=$article->find_by_id(1);
$article->remove_tags($tag);
 
Récupérée de « http://wiki.nano-framework.com/index.php/Exemple »