---
# System prepended metadata

title: Flow - Créer un module - documentation

---

# Flow - Créer un module - documentation
## Table des matières
[Introduction](#Introduction)
- [I - Créer la base du module](#I-Créer-la-base-du-module)
    - [A - Définir les tables de la base de données](#A-Définir-les-tables-de-la-base-de-données)
    - [B - Créer le dossier et la base des fichiers](#B-Créer-le-dossier-et-la-base-des-fichiers)
- [II - Configuration du module](#II-Configuration-du-module)
    - [A - Nommage des fichiers](#A-Nommage-des-fichiers)
    - [B - Configuration des fichiers](#B-Configuration-des-fichiers)
    - [C - Méthodes utiles](#C-Méthodes-utiles)
- [III - Création des Vues](#III-Création-des-Vues)
## Introduction
## I) Créer la base du module
### A) Définir les tables de la base de données:
- Lire le devis pour comprendre les attentes liées au module.
- Faire un Modèle conceptuel des données.
Exemple:
![](https://i.imgur.com/eUTFZq5.png)
- Pour le MCD:
    * Ne pas oublier la colonne "lng" (langue) pour toutes les tables qui sont traduisibles.
    * La colonne "lng" fait partie de la clé primaire.
    * Pour ajouter ulterieurement la fonctionnalité trier, ajouter la colonne "sort" dans la table.
    * Pour ajouter ulterieurement la fonctionnalité trier et gérer des sous-catégories, ajouter les colonnes "left", "right" et "level".
    * Ajouter les colonnes "date_creation" et "date_modification".
- Créer les tables sur adminer.
- Ajouter les clés secondaires.
- Les tables se nomment: [nomModule]_[nomTable]

---

### B) Créer le dossier et la base des fichiers
Pour créer le dossier et les fichiers aller dans l'URL:
```
/tools/admin/create_daocrud/[nomTable]/[nomModule]
```

Exemple:
- Le nom de la table: team_member
- Le nom du module: team
```
/tools/admin/create_daocrud/member/team
```

---
---


## II) Configuration du module
### A) Nommage des fichiers
#### 1) Controllers
Le controleur fait le lien entre la vue et le modèle.
##### a) controllers/Admin_....php
- Les controleurs qui servent à l'administration sont nommés avec "Admin_[nom table]". Ces controleurs permettent d'afficher, créer ou modifier les données d'une table.
- Si la table est le lien entre deux tables, le controleur se nomme "Admin_[nom table 1]_[nom table 2]".

##### b) controllers/....php
- Les controleurs avec le nommage "[Nom table].php" permettent d'afficher les vues sur le site.

#### 2) Models
Le modèle fait le lien avec les tables de la base de donnée.
##### a) models/...model.php
- Les modèles ont le nommage "[Nom table]model.php".
- Si la table est le lien entre deux tables, le modèle se nomme "[Nom table 1]_[nom table 2]model.php".

#### 3) Views
La vue permet d'afficher la page sur le site.
##### a) views/..._form.php
- Les vues pour l'administration se nomment [Nom table]_form.php.

##### b) views/....php
- Les vues pour le site se nomme [Nom table].php.

---

### B) Configuration des fichiers
#### 1) Controllers
##### a) Administration
- Le controleur hérite d'Admin_controller.
```
<?php
namespace nomModule;

class Admin_nomTable extends \Admin_controller
{

    protected $models = ['nomModule/nomTable' => 'nomModule_nomTable'];
    protected $model = 'nomModule_nomTable';
    protected $list_properties = ['key', 'name'];
    protected $edit_properties = [
        'lang' => ['name', 'description'],
        'admin' => ['key']
    ];
    protected $edit_form = 'nomModule/nomTable_form';
    protected $edit_find_method = 'find_adv';
    protected $list_buttons_left = ['sort' => null];
    protected $list_buttons_right = ['update' => ':update', 'duplicate' => ':duplicate', 'delete' => ':delete'];
    protected $list_buttons_top = ['back' => 'nomModule~admin_nomAutreTable:liste', 'add' => ':add', 'search' => ['redirect' => 'self']];
    protected $list_buttons_bottom = [];
    protected $list_find_method = 'find_by_lang';
    protected $list_filters = [
        'date_condition' => ['today' => 'today', 'yesterday' => 'yesterday', 'last monday' => 'week', 'month' => 'month', 'datepicker' => 'datepicker'],
    ];
    protected $upload_config = [
        'img' => [
            'name' => 'img',
            'upload_path' => 'nomModule/nomTable/',
            'overwrite' => false,
            'allowed_types' => 'gif|jpg|png|svg',
            'max_size' => 4000,
            'file_name' => null,
            'max_resolution' => 1920,
        ]
    ];


    public function liste($prop = null, $way = null, $data = [], $conditions = [])
    {
        // Filters
        parent::liste($prop, $way, $data, $conditions);
    }
    
    //
}

```
- namespace: Permet d'éviter les doublons avec les autres modules.
- $models: Les modèles que l'on utilise.
- $model: Le modèle relié à la table.
- $list_properties: Les colonnes affichées dans la liste de l'administration.
- $edit_properties: Lors de la modification les colonnes qui peuvent être modifier.
    - 'lang' ou 'admin': onglet de l'administration. Les plus utilisés:
        - 'general': les colonnes qui n'ont pas besoin d'être traduite.
        - 'lang': toutes les colonnes qui sont traduisibles.
        - 'admin': on y met le plus souvent la clé, l'activation.
        - 'photo': gestion des images.
        - 'sidebar': s'affiche sur le côté droit.
    - 'name', 'description' ou 'key': le nom des colonnes qui peuvent être modifiées.
- $edit_form: Vue modifiée pour afficher certains éléments.
- $edit_find_method: Méthode pour éditer.
- $list_buttons_left: A utiliser quand on veut permettre de classer les titres.
- $list_buttons_right: Outils de modification.
- $list_buttons_top: Boutons en haut de la page. C'est ici où il y a le bouton ajouter.
    - 'back': permet d'aller vers une autre administration.
        - Pour les liens: 'nomModule~admin_nomAutreTable:liste'.
    - 'add': permet d'aller sur la page ajouter.
        - Lien: ':add'.
- $list_buttons_bottom: Boutons en bas de la page.
- $list_find_method: Méthode pour afficher les données dans l'administration.
    - 'find_by_lang': Pour afficher les données quand il y a une traduction.
- $list_filters: Filtres dans l'administration.
- $upload_config: Pour uploader un fichier sur le site:
    - 'name': Nom de la colonne.
    - 'upload_path': URL du fichier.
    - 'overwrite': Ajouter au dessus.
    - 'allowed_types': Les types de fichiers autorisés.
    - 'max_size': Taille maximal en KB.
    - 'file_name': Le nom du fichier, si null prend le nom du fichier uploadé.
    - 'max_resolution': résolution maximale.

Exemple:
- Le controleur est Admin_member.php.
- Le module est team.
- On a besoin de la table team_group et team_title.
- Il faut une vue spéciale pour afficher les groupes et les titres à cocher: member_form.
- 
```
<?php
namespace team;

class Admin_member extends \Admin_controller
{

    protected $model = 'member';
    protected $models = ['team/member', 'team/group' => 'team_group', 'team/title', 'team/member_title'];
    protected $list_properties = ['id', 'firstname', 'lastname', 'key_group'];
    protected $edit_properties = [
        'general' => ['firstname', 'lastname', 'key_group', 'link_linkedin'],
        'lang' => ['description'],
        'photo' => ['img'],
        'admin' => ['id', 'enabled'],
        'sidebar' => ['team_title'],

    ];
    protected $edit_find_method = 'find_adv';
    protected $edit_form = 'team/member_form';
    protected $list_buttons_top = ['group_list' => 'team~admin_group:liste', 'title_list' => 'team~admin_title:liste', 'add' => ':add', 'search' => ['redirect' => 'self']];
    protected $list_buttons_right = ['toggle_state' => ':toggle_state', 'update' => ':update', 'delete' => ':delete'];
    protected $list_find_method = 'find_by_lang';
    protected $list_filters = [
        'date_condition' => ['today' => 'today', 'yesterday' => 'yesterday', 'last monday' => 'week', 'month' => 'month', 'datepicker' => 'datepicker'],
    ];

    protected $upload_config =
        [
            'img' => [ // field name
                'name' => 'img',
                'upload_path' => 'team/member/', // suffix after MY_IMAGE_PATH with the trailing slash
                'overwrite' => false,
                'allowed_types' => 'gif|jpg|png|svg',
                'max_size' => 4000, // in kB
                'file_name' => null, // null keep original name, empty string generate a random name
                'max_resolution' => 1920, // resolution width or height, 0 to keep original size
            ]
        ];

    public function add($data = [])
    {
        $data = $this->_init_data($data);
        parent::add($data);
    }

    public function update($full_pk = null, $data = [])
    {
        $data = $this->_init_data($data, $full_pk);
        parent::update($full_pk, $data);
    }


    public function liste($prop = null, $way = null, $data = [], $conditions = [])
    {
        // Filters
        $this->list_filters['team_member.enabled'] = ['0' => t(':disabled'), '1' => t(':enabled')];
        $this->list_filters['team_member.key_group'] = $this->team_groupmodel->dropdown('key', 'name', false, ['lng' => LNG]);
        parent::liste($prop, $way, $data, $conditions);
    }

    protected function _init_data($data = [], $id = null)
    {
        $data['key_group'] = $this->team_groupmodel->dropdown('key', 'name', false);
        $data['team_title'] = $this->titlemodel->dropdown('key', 'name', false);
        $data['team_c_title'] = $this->member_titlemodel->dropdown('key_title', 'key_title' ,false , ['id_member' => $id]);
        return $data;
    }
}
```

##### b) Site
- Le controleur hérite de Front_controller.
```
<?php
namespace nomModule;

class NomTable extends \Front_controller
{
    protected $models = ['nomModule/nomTable', 'nomModule/nomTable' => 'nomModule_nomTable', 'nomModule/'nomTable', 'nomModule/'nomTable'];
    protected $view_inside= 'nomModule/view';
    protected $module = 'nomModule';
    protected $allowed_search_conditions = ['nomColonne','nomColonne','nomColonne'];

    protected $access = [
        '*'=> false,
    ];

    //Methodes

}
```

- namespace: Permet d’éviter les doublons avec les autres modules.
- $models: Les modèles que l’on utilise.
- $view_inside: Chemin du dossier des vues.
- $module: Nom du module.
- $allowed_search_conditions: Colonnes qui sont authorisées à être cherchées.
- $access: Autorisation d'accès à la page.

Exemple:
```
<?php
namespace team;

class Member extends \Front_controller
{
    protected $models = ['team/member', 'team/group' => 'team_group', 'team/title', 'team/member_title'];
    protected $view_inside= 'team/view';
    protected $module = 'team';
    protected $allowed_search_conditions = ['firstname','lastname','key_group'];

    protected $access = [
        '*'=> false,
    ];

    /***
     * Display page profile member
     * @param $id int key for team_member
     * @route team/member/profile/$1
     * @route equipe/member/$1
     **/
    public function profile($id)
    {
        $this->load->library('view_read');

        // Get page for templating only at this point
        $this->load->model('page/pagemodel');
        $page = $this->pagemodel->get('team~member:profile');

        // _init_front
        $data['module'] = $this->module;
        $data['page'] = $this->module.'/member';

        // Main request
        $conditions['id_member'] = $id;
        $data['member'] = $this->membermodel->find_join($conditions);
        $data['member'] = $data['member'][0];
        if($data['member'] != NULL) {
            $this->load->view('fastsite/index', $data);
        }
        else{
            show_404();
        }
    }

    /**
     * Load member into $data['row']
     * @param $id int key for team_member
     * @param $data array
     * @return $data
     */
    protected function _load_member($id, $data)
    {
        // If row is already present get out
        if (!isset($data['row'])) {
            // Product
            $data['row'] = $this->membermodel->get_join($id, ['id', 'firstname', 'lastname', 'key_group', 'img', 'link_linkedin', 'enabled']);
        }
        return $data;
    }

    protected function compare($a, $b)
    {
        if(isset($a->titles[0]) && isset($b->titles[0])) {
            return strcmp($a->titles[0]->sort, $b->titles[0]->sort);
        }
        else if(isset($a->titles[0]) && !isset($b->titles[0])){
            return false;
        }
        return true;
    }

    /***
     * Display page list members
     * @route team/member/all
     * @route equipe/all
     **/
    public function all($group = null) {
        $this->load->library('view_read');

        // Get page for templating only at this point
        $this->load->model('page/pagemodel');
        $page = $this->pagemodel->get('team~member:all');
        $data['team_groups_nav'] = $this->team_groupmodel->find_fill('', ['sort' => 'ASC']);
        $conditions = [];
        if(isset($group)){
            $test = 0;
            foreach ($data['team_groups_nav'] as $grouptest) {
                if ($group == $grouptest->key) {
                    $conditions['group'] = $group;
                    $data['group_test'] = $group;
                    $test = 1;
                }
            }
            if($test == 0){
                show_404();
            }
        }
        // _init_front
        $data['module'] = $this->module;
        $data['page'] = $this->module.'/members';
        // Main request
        $data['team_groups'] = $this->team_groupmodel->find_by_lang('', ['sort' => 'ASC']);
        $members = $this->membermodel->find_join($conditions);
        uasort($members, [$this,'compare']);
        $data['members'] = $members;
        if($data['members'] != NULL) {
            $this->load->view('fastsite/index', $data);
        }
        else{
            redirect();
        }
    }
}

```

#### 2) Models
```
<?php
namespace nomModule;

class nomTablemodel extends \fastsite\Daomodel
{

    protected $table = 'nomModule_nomTable';
    protected $pk = ['cléPrimaire', 'lng']; //value or array for multiple PKs
    protected $orderby = ['colonne' => 'asc'];
    public $properties = ['colonne', 'colonne', 'colonne', 'colonne', 'colonne', 'colonne', 'colonne', 'colonne', 'colonne', 'colonne', 'colonne'];
    public $lang_properties = ['colonne'];

    // Array of methods to be called before or after a record is created or updated
    protected $before_create = ['_prepareCreate'];
    protected $before_lang_create = ['_prepareLangCreate'];
    protected $after_create = ['_afterCreate', '_createTitle'];
    protected $before_update = ['_prepareUpdate'];
    protected $before_lang_update = ['_prepareLangUpdate'];
    protected $after_update = ['_afterUpdate', '_saveTitle'];

    // Methodes
}
```

- namespace: Permet d’éviter les doublons avec les autres modules.
- $table: Nom de la table reliée au modèle.
- $pk: Clé(s) primaire(s), Ajouter "lng" si il y a une traduction.
- $orderby: ordre de classement.
    - Colonne pour classer.
    - Termes de recherche:
        - ASC: Croissant ![](https://i.imgur.com/aneQUC3.png)
        - DESC: Décroissant
- $properties: toutes les colonnes de la table.
- $lang_properties: toutes les colonnes qui sont traduisibles.
- $before_create: méthode appelée avant la création de la ligne.
- $before_lang_create: méthode appelée avant la création de la ligne traduisible.
- $after_create: méthode appelée après la création de la ligne.
- $before_update: méthode appelée avant la modification de la ligne.
- $before_lang_update: méthode appelée après la création de la ligne traduisible.
- $after_update: méthode appelée après la modification de la ligne.

Exemple:
```
<?php
namespace team;

class Membermodel extends \fastsite\Daomodel
{

    protected $table = 'team_member';
    protected $pk = ['id', 'lng']; //value or array for multiple PKs
    protected $orderby = ['id' => 'asc'];
    public $properties = ['id', 'lng', 'firstname', 'lastname', 'key_group', 'description', 'img', 'link_linkedin', 'enabled', 'date_creation', 'date_modification'];
    public $lang_properties = ['description'];

    // Array of methods to be called before or after a record is created or updated
    protected $before_create = ['_prepareCreate'];
    protected $before_lang_create = ['_prepareLangCreate'];
    protected $after_create = ['_afterCreate', '_createTitle'];
    protected $before_update = ['_prepareUpdate'];
    protected $before_lang_update = ['_prepareLangUpdate'];
    protected $after_update = ['_afterUpdate', '_saveTitle'];

    /***
     * Recover data
     * @param $id int key for team_member
     * @param $adv array columns to recover of table team_member
     * @return $rec
     **/
    public function get_join($id, $adv = [])
    {
        if (!is_array($id)) {
            $id = [$id];
        }
        $rec = $this->get($id);
        if ($rec) {
            $rec = $this->_init_front($rec, $adv);
            if ($this->use_api) {
                $rec = $this->_cleanup_api_record($rec);
            }
        }
        return $rec;
    }

    public function find_last()
    {
        $this->db->select('id');
        $this->db->from('team_member');
        $this->db->order_by('id', 'DESC');
        $this->db->limit(1);
        $query = $this->db->get();
        return $query->result();
    }

    /***
     * Recover data
     * @return $rs
     **/
    public function find_join($conditions = [], $orderby = null, $limit = null, $fields = null, $adv = [], $dropdowns = null, $group_by = null, $calc_rows = true)
    {
        $this->db->select($adv);
        $this->db->from('team_member');
        $this->db->join('team_group', 'team_member.key_group = team_group.key AND team_group.lng = "'.LNG.'"', 'left outer');
        $this->db->order_by('team_group.sort', 'ASC');
        if (isset($conditions['id_member'])) {
            $this->db->where('team_member.id', $conditions['id_member']);
        }
        if (isset($conditions['group'])) {
            $group = $conditions['group'];
            $this->db->where('team_member.key_group', $group);
        }
        $this->db->where('team_member.lng', LNG);
        $this->db->where('team_member.enabled', 1);
        $query = $this->db->get();
        if ($calc_rows) {
            $this->total_rows = $this->total_rows();
        }
        $rs = $query->result();
        foreach ($rs as $rec) {
            if ($adv !== false) {
                $rec = $this->_init_front($rec, $adv);
            }
            if ($this->use_api) {
                $rec = $this->_cleanup_api_record($rec);
            }
        }
        return $rs;
    }

    protected function _init_front($rec, $adv = [])
    {
        // main url
        if (is_array($adv) && in_array('url', $adv)) {
            $rec->url = my_url($rec->id, 'team~member');
        }

        if (!$adv || in_array('title', $adv)) {
            $rec->titles = $this->titlemodel->find_join_member(['id_member' => $rec->id], ['sort' => 'ASC']);
        }
        return $rec;
    }

    protected function _prepareCreate($record)
    {
        $lastid = $this->find_last();
        $lastid =  $lastid[0]->id;
        $lastid++;
        $record->id = $lastid;
        $record->date_creation = date('Y-m-d H:i:s');
        $record->date_modification = date('Y-m-d H:i:s');
        return $record;
    }

    protected function _prepareUpdate($record, $key)
    {
        $record->date_modification = date('Y-m-d H:i:s');
        return $record;
    }

    protected function _prepareLangCreate($record, $lang)
    {
        return $record;
    }

    protected function _prepareLangUpdate($record, $lang, $key)
    {
        $record->date_modification = date('Y-m-d H:i:s');
        return $record;
    }

    protected function _afterCreate($record, $key)
    {
        $this->_createTitle($record, $key);
        return $record;
    }

    protected function _afterUpdate($record, $key)
    {
        $this->_saveTitle($record, $key);
        return $record;
    }

    protected function _createTitle($record, $id)
    {
        $this->db->delete('team_member_title', ['id_member' => $id['id']]);
        $titles = $this->input->post('team_title');
        $num = 0;
        if ($titles != NULL) {
            foreach ($titles as $title) {
                $rec = new \stdClass();
                $rec->id_member = $id['id'];
                $rec->key_title = $title;
                $this->member_titlemodel->add($rec);
            }
        }
        return $record;
    }

    protected function _saveTitle($record, $id)
    {
        $this->db->delete('team_member_title', ['id_member' => $id]);
        $titles = $this->input->post('team_title');
        $num = 0;
        if ($titles != NULL) {
            foreach ($titles as $title) {
                $rec = new \stdClass();
                $rec->id_member = $id;
                $rec->key_title = $title;
                $this->member_titlemodel->add($rec);
            }
        }
        return $record;
    }

    public function find_by_lang($conditions=array(), $orderby=null, $limit=null, $fields=null) {
        $conditions['team_member.lng'] = LNG;
        return $this->find($conditions, $orderby, $limit, $fields);
    }

    /**
     * Init advanced an object
     */
    protected function _init_adv($rec, $adv=null) {
        if (!$adv || in_array('title', $adv)) {
            $rec->titles = $this->titlemodel->find_join_member(['id_member' => $rec->id]);
        }
        return $rec;
    }
}

```
#### 3) View
##### a) Administration
- Cette vue permet de modifier l'administration. Par exemple afficher dans l'administration une liste déroulante récupérant les lignes d'une autre table.
- Ajouter une liste déroulante ajouter:
`echo form_dropdown($prop, $$prop, set_value($prop, isset($row->$prop)?$row->$prop:''));`

- Ajouter une liste de check box:
```
foreach ($$prop as $titles => $title)
{
    echo form_checkbox([
        'name' => $prop.'[]',
        'id' => 'title_'.$titles,
        'checked' => in_array($titles, $team_c_title)],
        $titles);
    echo '<label for="title_'.$titles.'" style="display: inline-block; width: auto">'.$title.'</label>';
    echo '<br/>';
}
```
- Ajouter des boutons radios:
```
$value = set_value($prop, (isset($row->$prop)?$row->$prop:null));
                        echo form_radio($prop, 1, $value==='1');
                        echo img_tag_admin('admin/fs2/btn_enabled.png');
                        echo form_radio($prop, 0, $value==='0');
                        echo img_tag_admin('admin/fs2/btn_disabled.png');
```
- Ajouter un textarea:
```
echo form_textarea([
    'name' => $prop.'['.$row->cle_lang.']',
    'value' => set_value($prop.'['.$row->cle_lang.']', isset($row->$prop)?$row->$prop:'', false),
    'class' => 'tinymce',
    'style' => 'width:99%',
    'rows' => '20']);
```
- Ajouter un upload:
```
echo form_img_upload($prop, set_value($prop, isset($row->$prop)?$row->$prop:''), $upload[$prop]);
echo '<span class="clear"></span>';
```
- Ajouter un input text:
`echo form_input($prop.'['.$row->cle_lang.']', set_value($prop.'['.$row->cle_lang.']', isset($row->$prop)?$row->$prop:''));`

Exemple:
```
<?php
if (count($properties)) {
    foreach ($properties as $label=>$sub_properties) {
        if ($label=='lang') {
            foreach ($results as $row) {
                echo '<div class="domdiv'.$has_sidebar.'" id="'.$row->cle_lang.'">';
                foreach ($sub_properties as $prop) {
                    echo '<p id="'.crud_id($module_controller, $prop, $row->cle_lang).'">';
                    echo form_label(tb(':'.$prop), $prop.'['.$row->cle_lang.']');
                    switch ($prop) {
                        case 'img' :
                            echo form_img_upload($prop.'['.$row->cle_lang.']', set_value($prop.'['.$row->cle_lang.']', isset($row->$prop)?$row->$prop:''), $upload[$prop]);
                            echo '<span class="clear"></span>';
                            break;
                        case 'description' :
                        case 'content':
                            echo form_textarea(array(
                                'name' => $prop.'['.$row->cle_lang.']',
                                'value' => set_value($prop.'['.$row->cle_lang.']', isset($row->$prop)?$row->$prop:'', false),
                                'class' => 'tinymce',
                                'style' => 'width:99%',
                                'rows' => '20'));
                            break;
                        case 'history':
                            $this->load->view('fastsite/crud_history');
                            break;
                        default:
                            echo form_input($prop.'['.$row->cle_lang.']', set_value($prop.'['.$row->cle_lang.']', isset($row->$prop)?$row->$prop:''));
                    }
                    echo '</p>';
                }
                echo '</div>';
            }
        } else {
            echo '<div class="'.($label == 'sidebar'?'formvertical w30':'domdiv'.$has_sidebar).'" id="t'.$label.'">';
            foreach ($sub_properties as $prop) {
                echo '<p id="'.crud_id($module_controller, $prop).'">';
                echo form_label(tb(':'.$prop), $prop);
                switch ($prop) {
                    case 'img' :
                        echo form_img_upload($prop, set_value($prop, isset($row->$prop)?$row->$prop:''), $upload[$prop]);
                        echo '<span class="clear"></span>';
                        break;
                    case 'enabled' :
                        $value = set_value($prop, (isset($row->$prop)?$row->$prop:null));
                        echo form_radio($prop, 1, $value==='1');
                        echo img_tag_admin('admin/fs2/btn_enabled.png');
                        echo form_radio($prop, 0, $value==='0');
                        echo img_tag_admin('admin/fs2/btn_disabled.png');
                        break;
                    case 'description' :
                    case 'content':
                        echo form_textarea(array('name'=>$prop, 'value'=>set_value($prop, isset($row->$prop)?$row->$prop:''), 'cols'=>'40', 'rows'=>'2', 'class'=>'autoresize'));
                        break;
                    case 'history':
                        $this->load->view('fastsite/crud_history');
                        break;
                    case 'component':
                        $this->load->view('component/component_template_form');
                        break;
                    case 'key_group':
                        echo form_dropdown($prop, $$prop, set_value($prop, isset($row->$prop)?$row->$prop:''));
                        break;
                    case 'team_title':
                        //echo '<span style="display: inline-block">';
                        foreach ($$prop as $titles => $title)
                        {
                            echo form_checkbox([
                                'name' => $prop.'[]',
                                'id' => 'title_'.$titles,
                                'checked' => in_array($titles, $team_c_title)],
                                $titles);
                            echo '<label for="title_'.$titles.'" style="display: inline-block; width: auto">'.$title.'</label>';
                            echo '<br/>';
                        }
                        //echo '</span>';
                        break;
                    case $pk :
                        if ($mode == 'update') {
                            echo '<span class="readonly">'.$row->$prop.'</span>';
                            break;
                        }
                    default :
                        echo form_input($prop, set_value($prop, isset($row->$prop)?$row->$prop:''));
                }
                echo '</p>';
            }
            echo '</div>';
        }
    }
}
```

##### b) Site
Intégration de la page en php.

---

### C) Méthodes utiles
#### 1) Controllers
##### a) Administration
- Ajouter une ligne
```
public function add($data = [])
    {
        $data = $this->_init_data($data);
        parent::add($data);
    }
```

- Modifier une ligne
```
public function update($full_pk = null, $data = [])
    {
        $data = $this->_init_data($data, $full_pk);
        parent::update($full_pk, $data);
    }
```

- Initialiser les données
```
protected function _init_data($data = [], $id = null)
    {
        $data['nomDesDonnées'] = $this->nomModel->dropdown('key_title', 'key_title' ,false , ['colonne' => $id]);
        return $data;
    }
``` 

- Ajouter des filtres
```
public function liste($prop = null, $way = null, $data = [], $conditions = [])
    {
        // Filters
        //Enabled
        $this->list_filters['nomTable'.enabled'] = ['0' => t(':disabled'), '1' => t(':enabled')];
        //Colonne
        $this->list_filters['nomTable.colonne'] = $this->nomModule_nomModele->dropdown('key', 'name', false, ['lng' => LNG]);
        parent::liste($prop, $way, $data, $conditions);
    }
```

##### b) Site
- Afficher la vue
    - S'il n'y a pas de donnée, afficher la 404.
    - Pour trouver la cléPage:
        - Administration > CMS > Pages > éditer la page voulue > Admin > Clé

```
public function nomVue($parametre)
    {
        $this->load->library('view_read');

        // Get page for templating only at this point
        $this->load->model('page/pagemodel');
        $page = $this->pagemodel->get('cléPage');

        // _init_front
        $data['module'] = $this->module;
        $data['page'] = $this->module.'/nomControllerVue';

        // Main request
        $conditions['colonne'] = $parametre;
        $data['colonne'] = $this->nomModele->find_join($conditions);
        $data['colonne'] = $data['colonne'][0];
        if($data['colonne'] != NULL) {
            $this->load->view('fastsite/index', $data);
        }
        else{
            show_404();
        }
    }

```

#### 2) Modele
- Trouver la dernière ligne
```
public function find_last()
    {
        $this->db->select('id');
        $this->db->from('team_member');
        $this->db->order_by('id', 'DESC');
        $this->db->limit(1);
        $query = $this->db->get();
        return $query->result();
    }
```

- Trouver et joindre une autre table
```
public function find_join($conditions = [], $orderby = null, $limit = null, $fields = null, $adv = [], $dropdowns = null, $group_by = null, $calc_rows = true)
    {
        $this->db->select($adv);
        $this->db->from('prefix_nomTable');
        $this->db->join('prefix_nomAutreTable', 'prefix_nomTable.cleTable = prefix_nomAutreTable.cleliée AND prefix_nomAutreTable.lng = "'.LNG.'"', 'left outer');
        $this->db->order_by('prefix_nomAutreTable.colonne', 'ASC');
        $this->db->where('prefix_nomTable.colonne', $conditions);
        $this->db->where('prefix_nomTable.lng', LNG);
        $this->db->where('prefix_nomTable.enabled', 1);
        $query = $this->db->get();
        if ($calc_rows) {
            $this->total_rows = $this->total_rows();
        }
        $rs = $query->result();
        foreach ($rs as $rec) {
            if ($adv !== false) {
                $rec = $this->_init_front($rec, $adv);
            }
            if ($this->use_api) {
                $rec = $this->_cleanup_api_record($rec);
            }
        }
        return $rs;
    }
```

- Chercher et trouver par la langue
```
public function find_by_lang($conditions=array(), $orderby=null, $limit=null, $fields=null)
    {
        $conditions['prefix_nomTable.lng'] = LNG;
        return $this->find($conditions, $orderby, $limit, $fields);
    }
```

- Initialisation du front
```
protected function _init_front($rec, $adv = [])
    {
        // main url
        if (is_array($adv) && in_array('url', $adv)) {
            $rec->url = my_url($rec->id, 'nomModule~nomModelesufix');
        }

        if (!$adv || in_array('title', $adv)) {
            $rec->titles = $this->titlemodel->find_join_member(['id_member' => $rec->id], ['sort' => 'ASC']);
        }
        return $rec;
    }
```

- 
---
---


## III) Création des Vues
Pour créer une vue:
- Aller dans Pages
![](https://i.imgur.com/Ifi2AzK.png)
- Créer une nouvelle page
![](https://i.imgur.com/yDdRer3.png)
- Dans l'onglet langue (![](https://i.imgur.com/jEA8Y17.png) / ![](https://i.imgur.com/7xGm19I.png) ou autre), choisir un titre
    - Ne pas oublier de choisir pour les autres langues
- Dans l'onglet ![](https://i.imgur.com/NcpJDwb.png), choisir:
    - La clé de la page
        - Nommage de la clé: nomModule~nomFichierController:nomMethode
    - La method
        - nomModule/nomFichierController/nomMethode
- Enregistrer
![](https://i.imgur.com/ggUx2N3.png)