Dernière mise à jour : 19/02/2020 à 20h53
Table des matières
Mise en place des catégories
Pour mettre en place les catégories, il faut déclarer la table dans votre ModuleSetup et créer le fichier de Cache de vos catégories.
Deux types de catégories sont déclarées dans le noyau :
- Category : catégorie de base avec un nom et des autorisations
- RichCategory : catégorie de base + description et image
Rien ne vous empêche de créer votre propre type de catégorie en créant une classe fille de Category ou RichCategory, nous verrons ça dans l'utilisation avancée des catégories.
Création de la table dans la base de données
Pour créer la table dans la base de données, il suffit de déclarer son nom dans votre ModuleSetup et d'appeler la fonction de création de table de la classe Category ou RichCategory en fonction de votre besoin.
Code PHP :
<?php class MyModuleSetup extends DefaultModuleSetup { public static $mymodule_cats_table; public static function __static() { self::$mymodule_cats_table = PREFIX . 'mymodule_cats'; } public function install() { $this->create_tables(); } private function create_tables() { $this->create_mymodule_cats_table(); } // Appel de la fonction pour créer la table private function create_mymodule_cats_table() { RichCategory::create_categories_table(self::$mymodule_cats_table); } } ?>
Pensez également à mettre un champ id_category de type entier dans la table principale de votre module.
Classe qui va gérer le cache des catégories du module
Créez le fichier /mymodule/services/MyModuleCategoriesCache.class.php. Cette classe doit être une classe fille de CategoriesCache.
Code PHP :
<?php class DownloadCategoriesCache extends CategoriesCache { // Fonction qui retourne le nom de la table des catégories du module public function get_table_name() { return MyModuleSetup::$mymodule_cats_table; } // Fonction qui retourne la classe de la catégorie (CategoriesManager::STANDARD_CATEGORY_CLASS ou CategoriesManager::RICH_CATEGORY_CLASS) public function get_category_class() { return CategoriesManager::RICH_CATEGORY_CLASS; } // Fonction qui retourne le nom du module public function get_module_identifier() { return 'mymodule'; } // Fonction qui permet de compter le nombre d'éléments dans une catégorie protected function get_category_elements_number($id_category) { $now = new Date(); return MyModuleService::count('WHERE id_category = :id_category AND approved = 1'); } // Fonction qui permet de spécifier les autorisations (et la description si RICH_CATEGORY) de la catégorie racine du module public function get_root_category() { $root = new RichRootCategory(); $root->set_authorizations(MyModuleConfig::load()->get_authorizations()); $root->set_description(MyModuleConfig::load()->get_root_category_description()); return $root; } } ?>
Services du module
Créez le fichier /mymodule/services/MyModuleService.class.php. Ce module contiendra les différentes actions à effectuer vis à vis de la base de données du module (ajout, édition, suppression, ...) et permet de récupérer la classe de gestion des catégories adaptée au module (ce qui nous intéresse ici, donc seule cette partie apparait ci-dessous).
Code PHP :
<?php class MyModuleService { private static $categories_manager; /** * @desc Return the authorized categories. */ public static function get_authorized_categories($current_id_category) { $search_category_children_options = new SearchCategoryChildrensOptions(); $search_category_children_options->add_authorizations_bits(Category::READ_AUTHORIZATIONS); if (AppContext::get_current_user()->is_guest()) $search_category_children_options->set_allow_only_member_level_authorizations(MyModuleConfig::load()->are_descriptions_displayed_to_guests()); $categories = self::get_categories_manager()->get_children($current_id_category, $search_category_children_options, true); return array_keys($categories); } /** * @desc Return the categories manager. */ public static function get_categories_manager() { if (self::$categories_manager === null) { $categories_items_parameters = new CategoriesItemsParameters(); //Table principale du module $categories_items_parameters->set_table_name_contains_items(MyModuleSetup::$mymodule_table); self::$categories_manager = new CategoriesManager(MyModuleCategoriesCache::load(), $categories_items_parameters); } return self::$categories_manager; } } ?>
Autorisations
La mise en place d'un service pour les autorisations vous permettra d'accéder facilement aux différentes autorisations des catégories de votre module.
Créez le fichier /mymodule/services/MyModuleAuthorizationsService.class.php.
Code PHP :
<?php class MyModuleAuthorizationsService { public $id_category; public static function check_authorizations($id_category = Category::ROOT_CATEGORY) { $instance = new self(); $instance->id_category = $id_category; return $instance; } public function read() { return $this->is_authorized(Category::READ_AUTHORIZATIONS, Authorizations::AUTH_PARENT_PRIORITY); } public function write() { return $this->is_authorized(Category::WRITE_AUTHORIZATIONS); } public function contribution() { return $this->is_authorized(Category::CONTRIBUTION_AUTHORIZATIONS); } public function moderation() { return $this->is_authorized(Category::MODERATION_AUTHORIZATIONS); } private function is_authorized($bit, $mode = Authorizations::AUTH_CHILD_PRIORITY) { $auth = MyModuleService::get_categories_manager()->get_heritated_authorizations($this->id_category, $bit, $mode); return AppContext::get_current_user()->check_auth($auth, $bit); } } ?>
Pour vérifier l'autorisation d'écriture dans une catégorie, il suffit ensuite d'utiliser l'appel ($id_category est optionnel, s'il est omis les autorisations générales du module s'appliquent) :
Code PHP :
MyModuleAuthorizationsService::check_authorizations($id_category)->read()
Mise en place des url
Cette partie traite la mise en place des différentes url sur les pages pour accéder à la gestion et l'affichage des catégories.
Constructeur d'Url
L'UrlBuilder permet de définir les url qui seront utilisées dans votre module. Créez le fichier /mymodule/util/MyModuleUrlBuilder.class.php si ce n'est pas fait.
Code PHP :
<?php class MyModuleUrlBuilder { private static $dispatcher = '/mymodule'; //Ajout d'une catégorie public static function add_category($id_parent = null) { $id_parent = !empty($id_parent) ? $id_parent . '/' : ''; return DispatchManager::get_url(self::$dispatcher, '/admin/categories/add/' . $id_parent); } //Edition d'une catégorie public static function edit_category($id) { return DispatchManager::get_url(self::$dispatcher, '/admin/categories/' . $id . '/edit/'); } //Suppression d'une catégorie public static function delete_category($id) { return DispatchManager::get_url(self::$dispatcher, '/admin/categories/' . $id . '/delete/'); } //Gestion des catégories public static function manage_categories() { return DispatchManager::get_url(self::$dispatcher, '/admin/categories/'); } //Affichage d'une catégorie public static function display_category($id, $rewrited_name, $page = 1) { $category = $id > 0 ? $id . '-' . $rewrited_name . '/' : ''; $page = $page !== 1 ? $page . '/' : ''; return DispatchManager::get_url(self::$dispatcher, '/' . $category . $page); } } ?>
index
Le fichier index.php de votre module permet de faire le lien entre l'url demandée par l'utilisateur et le contrôleur à utiliser pour la traiter. indiquez les 5 UrlControllerMapper suivants :
Code PHP :
<?php define('PATH_TO_ROOT', '..'); require_once PATH_TO_ROOT . '/kernel/init.php'; $url_controller_mappers = array( //Categories new UrlControllerMapper('MyModuleCategoriesManageController', '`^/admin/categories/?$`'), new UrlControllerMapper('MyModuleCategoriesFormController', '`^/admin/categories/add/?([0-9]+)?/?$`', array('id_parent')), new UrlControllerMapper('MyModuleCategoriesFormController', '`^/admin/categories/([0-9]+)/edit/?$`', array('id')), new UrlControllerMapper('MyModuleDeleteCategoryController', '`^/admin/categories/([0-9]+)/delete/?$`', array('id')), new UrlControllerMapper('MyModuleDisplayCategoryController', '`^(?:/([0-9]+)-([a-z0-9-_]+))?/?([0-9]+)?/?$`', array('id_category', 'rewrited_name', 'page')) ); DispatchManager::dispatch($url_controller_mappers); ?>
Liens dans l'administration
Pour que les liens vers la gestion et l'ajout de catégories soit visibles dans l'administration, ajoutez le contenu suivant dans votre fichier /mymodule/util/AdminMyModuleDisplayResponse.class.php.
Code PHP :
$this->add_link(LangLoader::get_message('categories.management', 'categories-common'), MyModuleUrlBuilder::manage_categories()); $this->add_link(LangLoader::get_message('category.add', 'categories-common'), MyModuleUrlBuilder::add_category());
Menu d'actions
Pour que la gestion des catégories apparaisse dans le menu d'actions du module, ajoutez le contenu suivant dans votre fichier /mymodule/phpboost/MyModuleTreeLinks.class.php.
Code PHP :
$manage_categories_link = new AdminModuleLink(LangLoader::get_message('categories.manage', 'categories-common'), MyModuleUrlBuilder::manage_categories()); $manage_categories_link->add_sub_link(new AdminModuleLink(LangLoader::get_message('categories.manage', 'categories-common'), MyModuleUrlBuilder::manage_categories())); $manage_categories_link->add_sub_link(new AdminModuleLink(LangLoader::get_message('category.add', 'categories-common'), MyModuleUrlBuilder::add_category(AppContext::get_request()->get_getint('id_category', Category::ROOT_CATEGORY)))); $tree->add_link($manage_categories_link);
Administration
Au niveau administration, la gestion des catégories (et leur ajout / édition / suppression) est automatique, il suffit de mettre en place les contrôleurs suivants dans le dossier controllers de votre module. Pour plus de lisibilité, créez le répertoire /mymodule/controllers/categories.
Contrôleur de gestion des catégories
Dans ce dossier, créez le fichier MyModuleCategoriesManageController.class.php. La classe doit être une classe fille de AbstractCategoriesManageController.
Code PHP :
<?php class MyModuleCategoriesManageController extends AbstractCategoriesManageController { protected function generate_response(View $view) { return new AdminMyModuleDisplayResponse($view, $this->get_title()); } protected function get_categories_manager() { return MyModuleService::get_categories_manager(); } protected function get_display_category_url(Category $category) { return MyModuleUrlBuilder::display_category($category->get_id(), $category->get_rewrited_name()); } protected function get_edit_category_url(Category $category) { return MyModuleUrlBuilder::edit_category($category->get_id()); } protected function get_delete_category_url(Category $category) { return MyModuleUrlBuilder::delete_category($category->get_id()); } } ?>
Contrôleur d'ajout / édition
Créez le fichier MyModuleCategoriesFormController.class.php. La classe doit être une classe fille de AbstractRichCategoriesFormController si votre catégorie est une catégorie enrichie, AbstractCategoriesFormController sinon.
Code PHP :
<?php class MyModuleCategoriesFormController extends AbstractRichCategoriesFormController { protected function generate_response(View $view) { return new AdminMyModuleDisplayResponse($view, $this->get_title()); } protected function get_categories_manager() { return MyModuleService::get_categories_manager(); } protected function get_id_category() { return AppContext::get_request()->get_getint('id', 0); } protected function get_categories_management_url() { return MyModuleUrlBuilder::manage_categories(); } } ?>
Contrôleur de suppression
Créez le fichier MyModuleDeleteCategoryController .class.php. La classe doit être une classe fille de AbstractDeleteCategoryController.
Code PHP :
<?php class MyModuleDeleteCategoryController extends AbstractDeleteCategoryController { protected function generate_response(View $view) { return new AdminMyModuleDisplayResponse($view, $this->get_title()); } protected function get_categories_manager() { return MyModuleService::get_categories_manager(); } protected function get_id_category() { return AppContext::get_request()->get_getint('id', 0); } protected function get_categories_management_url() { return MyModuleUrlBuilder::manage_categories(); } } ?>
Flux RSS
Si vous souhaitez utiliser les flux RSS dans votre module, crééez le fichier /mymodule/phpboost/MyModuleFeedProvider.class.php. Cette classe doit implémenter la classe FeedProvider.
Code PHP :
<?php class MyModuleFeedProvider implements FeedProvider { public function get_feeds_list() { return MyModuleService::get_categories_manager()->get_feeds_categories_module()->get_feed_list(); } public function get_feed_data_struct($idcat = 0, $name = '') { if (MyModuleService::get_categories_manager()->get_categories_cache()->category_exists($idcat)) { $querier = PersistenceContext::get_querier(); $category = MyModuleService::get_categories_manager()->get_categories_cache()->get_category($idcat); $site_name = GeneralConfig::load()->get_site_name(); $site_name = $idcat != Category::ROOT_CATEGORY ? $site_name . ' : ' . $category->get_name() : $site_name; $feed_module_name = LangLoader::get_message('module_title', 'common', 'download'); $data = new FeedData(); $data->set_title($feed_module_name . ' - ' . $site_name); $data->set_date(new Date()); $data->set_link(SyndicationUrlBuilder::rss('mymodule', $idcat)); $data->set_host(HOST); $data->set_desc($feed_module_name . ' - ' . $site_name); $data->set_lang(LangLoader::get_message('xml_lang', 'main')); $data->set_auth_bit(Category::READ_AUTHORIZATIONS); $categories = MyModuleService::get_categories_manager()->get_children($idcat, new SearchCategoryChildrensOptions(), true); $ids_categories = array_keys($categories); $now = new Date(); $results = $querier->select('SELECT mymodule.* FROM ' . MyModuleSetup::$mymodule_table . ' mymodule LEFT JOIN '. MyModuleSetup::$mymodule_cats_table .' cat ON cat.id = mymodule.id_category WHERE mymodule.id_category IN :ids_categories AND mymodule.approved = 1 ORDER BY mymodule.creation_date DESC', array( 'ids_categories' => $ids_categories )); foreach ($results as $row) { $row['rewrited_name_cat'] = !empty($row['id_category']) ? $row['rewrited_name_cat'] : 'root'; $link = MyModuleUrlBuilder::display($row['id_category'], $row['rewrited_name_cat'], $row['id'], $row['rewrited_name']); $item = new FeedItem(); $item->set_title($row['name']); $item->set_link($link); $item->set_guid($link); $item->set_desc(FormatingHelper::second_parse($row['contents'])); $item->set_date(new Date($row['creation_date'], Timezone::SERVER_TIMEZONE)); $item->set_image_url($row['picture_url']); $item->set_auth(MyModuleService::get_categories_manager()->get_heritated_authorizations($row['id_category'], Category::READ_AUTHORIZATIONS, Authorizations::AUTH_PARENT_PRIORITY)); $data->add_item($item); } $results->dispose(); return $data; } } } ?>
Pensez également à indiquer la fonction suivante dans l'ExtensionPointProvider de votre module :
Code PHP :
public function feeds() { return new MyModuleFeedProvider(); }
Intégration dans le Plan du site
Tout a été fait pour que l'affichage des catégories dans le Plan du site se fasse automatiquement.
Si vous souhaitez que vos catégories apparaissent dans le plan du site, crééez le fichier /mymodule/phpboost/MyModuleSitemapExtensionPoint.class.php. Cette classe doit être une classe fille de SitemapCategoriesModule.
Code PHP :
<?php class MyModuleSitemapExtensionPoint extends SitemapCategoriesModule { public function __construct() { parent::__construct(MyModuleService::get_categories_manager()); } protected function get_category_url(Category $category) { return MyModuleUrlBuilder::display_category($category->get_id(), $category->get_rewrited_name()); } } ?>
Pensez également à indiquer la fonction suivante dans l'ExtensionPointProvider de votre module :
Code PHP :
public function sitemap() { return new MyModuleSitemapExtensionPoint(); }