PluXml.org

Blog ou CMS à l'Xml

Vous n'êtes pas identifié(e).

#1 04/12/2018 09:29:03

flipflip
Membre
Lieu : Lyon
Inscription : 19/05/2008
Messages : 768
Site Web

plugin, héritage de class

Bonjour,

Attention sujet bien poilu wink

Je dev un plugin pour pluxml (désolé dev interne à ma boite et très spécifique) qui comporte plusieurs modules. Une 1ere version a été mis en prod avec une class de presque 2000 lignes de codes et 1 an plus tard on me demande d'ajouter un module... Ouchhh voyant la taille de la class je prend peur et je me dis qu'ajouter un module va rendre la maintenance très complexe du coups je me lance dans l'idée de faire une class par module.

Je commence l'analyse en séparant les fonctions utilitaires et les fonctions propres à chaque modules et j'arrive à deux classes. Je déplace tout ce petit monde dans des fichiers séparé et je regarde comment sont montés les class de pluxml, en me basant sur plxMotor et plxShow, pour en reproduire la même logique.

Mon plugin s'appelle portail, le répertoire ce présente sous cette forme :

[== Indéfini ==]

-- portail
   |_ css
       |_ ...
   |_ js
       |_ ...
   |_ include
       |_ portail.php
       |_ portailAdv.php
       |_ ...
   |_ portail.php

dans portail.php pour le moment j'ai ce code :

[== PHP ==]
<?php

include(PLX_PLUGINS.'portail/include/portail.php');
include(PLX_PLUGINS.'portail/include/portailAdv.php');

$portail = portail::getInstance();
$portailAdv = portailAdv::getInstance();

?>

Dans include/portail.php (oui doublons de noms mais pour le moment j'ai pas trouvé mieux wink ) j'ai ce code :

[== PHP ==]
class portail extends plxPlugin {
	private static $instance;

	/**
	 * Méthode qui se charger de créer le Singleton portail
	 *
	 * @return	objet			return une instance de la classe portail
	 * @author	Stephane F
	 **/
	public static function getInstance(){
		if (!isset(self::$instance)) {
			self::$instance = false;
			self::$instance = new portail();
		}
		return self::$instance;
	}

	public function __construct($default_lang) {
		parent::__construct($default_lang);

		if(!empty($this->getParam('dbname'))) {
			try {
				$this->database = new Medoo([
						'database_type' => 'mysql',
						'database_name' => $this->getParam('dbname'),
						'server' => $this->getParam('dbhost'),
						'port' => $this->getParam('dbport'),
						'username' => $this->getParam('dbuser'),
						'password' => $this->getParam('dbpass'),
						'logging' => $this->getParam('debug')
				]);

				$this->addHook('portailRoutage', 'portailRoutage');
				$this->addHook('portailSidebarMenu', 'portailSidebarMenu');
			}
			catch (Exception $e) {
				echo $e->getMessage();
			}
		}

		# droit d'accès
		$this->setConfigProfil(PROFIL_ADMIN);
	}

	public function toto() {
		echo "portail.php";
	}

Dans include/portailAdv.php j'ai ce code

[== PHP ==]
class portailAdv {

  public $portail = false;
	private $lang;

	private static $instance = null;

	/**
	 * Méthode qui se charger de créer le Singleton plxShow
	 *
	 * @return	objet			return une instance de la classe plxShow
	 * @author	Stephane F
	 **/
	public static function getInstance(){
		if (!isset(self::$instance))
			self::$instance = new portailAdv();
		return self::$instance;
	}

	protected function __construct($default_lang) {
		$this->portail = portail::getInstance();

		$this->portail->toto();
	}

L'appel de la fonction toto me permet de vérifier si j'ai bien accès à la class mère portail depuis portailAdv et magie oui ça marche. Maintenant je fais le test inverse. Imaginons que la fonction toto se trouve dans la class portailAdv mais que je veuille l'appeler depuis la class mère portail.

Avec l'appel depuis la class portail :

[== PHP ==]
$portail->toto();

J'ai le message :

PHP Fatal error:  Call to a member function toto() on null in xxxx/plugins/portail/include/portail.php on line 52, referer: http:/xxxx/index.php?static18/portail

Toujours depuis la class portail :

[== PHP ==]
portailAdv::toto();

Je n'ai pas d'erreur mais un avertissement dans les logs

PHP Deprecated:  Non-static method portailAdv::toto() should not be called statically, assuming $this from incompatible context in xxxx/plugins/portail/include/portail.php on line 876, referer: http://xxx/index.php?static18/portail

J'ai testé la navigation sur le reste de mon site pour voir si une des class de pluxml créait le même message, pas d'erreur donc c'est mon implémentation qui déconne. Cela reste un avertissement mais à terme ça sera bloquant car marqué comme deprecated de php 7.0.

Avez-vous une idée du pourquoi problème ?


"J'ai un string dans l'array" | http://www.blogoflip.fr

Hors ligne

#2 04/12/2018 13:11:25

bazooka07
Membre
Lieu : Quelque part en Rhône-Alpes
Inscription : 06/02/2014
Messages : 1 180
Site Web

Re : plugin, héritage de class

Ton affaire a l'air compliqué et je ne suis pas sûr d'avoir tout capté.

AMHA, tu prends le problème par le mauvais bout.
la class Portail est un plugin et doit jouer un rôle prédominant.
Les modules doivent être totalement indépendants de PluXml. S'ils ont besoin de connaître le contexte, passer un paramètre aux méthodes qui en ont besoin

Le fichier Portail.php devrait ressembler à quelque chose comme ceci :

[== PHP ==]
<?php
defined('PLX_ROOT') or exit;

// déclaration de la class Module1 :
include __DIR__ . '/inc/module1.php';

// déclaration de la class Module2 :
include __DIR__ . '/inc/module2.php';

class Portail extends plxPlugin {
	private $__module1 = false;
	private $__module2 = false;
	
	public function __construct($lang) {
		parent::__construct($lang);
		
		if(!class_exists('Module1')) { die('class module1 absent'); }
		$self->__module1 = new Module1();
			
		if(!class_exists('Module2')) { die('class module2 absent'); }
		$self->__module2 = new Module2();
		
		// Déclaration des hooks
		$this->addHook('portailRoutage', 'portailRoutage');
		$this->addHook('portailSidebarMenu', 'portailSidebarMenu');
	}
	
	public function portailRoutage() {
		
	}
	
	public function portailSidebarMenu() {
		
	}
}
?>

Dernière modification par bazooka07 (04/12/2018 13:11:58)

Hors ligne

#3 05/12/2018 09:39:22

flipflip
Membre
Lieu : Lyon
Inscription : 19/05/2008
Messages : 768
Site Web

Re : plugin, héritage de class

Merci bazooka07 je vais tester.

Juste une question. Les modules de mon plugin sont effectivement indépendant de PluXml mais j'utilise régulièrement des fonctions du core de PluXml. Du coups avec ton code est-ce que j'aurais accès au fonction de pluxml ?


"J'ai un string dans l'array" | http://www.blogoflip.fr

Hors ligne

#4 05/12/2018 12:23:29

bazooka07
Membre
Lieu : Quelque part en Rhône-Alpes
Inscription : 06/02/2014
Messages : 1 180
Site Web

Re : plugin, héritage de class

Cela dépend.
Si ce sont des fonctions statiques, il n'y a pas de souci particulier. Il suffit juste de préciser la class avec le double caractère ":". Par exemple :
plxUtils::printSelect(...)

Si tu as besoin des données, articles, photos, page statiques, .., il y a 2 façons de faire :
- soit utiliser les variables globales $plxAdmin déclarée dans le fichier core/admin/prepend.php côté back-office, et  $plxMotor +  $plxShow déclarées dans le fichier index.php pour le front-office.
- soit utiliser les hooks natifs de PluXml avec de l'injection de code qui appelle une fonction de ton plugin. Tu ne pourras pas le faire avec tes modules, sauf s'il y a des méthodes statiques.

Dernière modification par bazooka07 (05/12/2018 12:24:20)

Hors ligne

#5 07/12/2018 11:51:50

flipflip
Membre
Lieu : Lyon
Inscription : 19/05/2008
Messages : 768
Site Web

Re : plugin, héritage de class

Re-bonjour,

J'essaie de comprendre le code que tu m'as proposé et il faut dire que pour le moment les class sont un peu obscurs pour moi wink

Voici le code que j'obtiens.

portail.php

[== PHP ==]
<?php
defined('PLX_ROOT') or exit;

include __DIR__.'/include/Medoo.php';
use Medoo\Medoo;

include __DIR__.'/include/portailUtils.php';
include __DIR__.'/include/portailAdv.php';

class portail extends plxPlugin {
	private $__portailUtils = false;
	private $__portailAdv = false;

	public function __construct($lang) {
		parent::__construct($lang);

		if(!class_exists('portailUtils')) { die('class portailUtils absent'); }
		$self->__portailUtils = new portailUtils();

		if(!class_exists('portailAdv')) { die('class portailAdv absent'); }
		$self->__portailAdv = new portailAdv();

    if(!empty($this->getParam('dbname'))) {
      try {
        $this->database = new Medoo([
            'database_type' => 'mysql',
            'database_name' => $this->getParam('dbname'),
            'server' => $this->getParam('dbhost'),
            'port' => $this->getParam('dbport'),
            'username' => $this->getParam('dbuser'),
            'password' => $this->getParam('dbpass'),
            'logging' => $this->getParam('debug')
        ]);
        // Déclaration des hooks
        $this->addHook('portailRoutage', 'portailRoutage');
        //$this->addHook('portailSidebarMenu', 'portailSidebarMenu');
      }
      catch (Exception $e) {
        echo $e->getMessage();
      }
    }
	}

	public function portailRoutage() {
		global $plxShow, $plxMotor;
		$error = false;

		if($this->getParam('debug')) {
			echo '<pre>';
			var_dump($_SESSION);
			var_dump($_POST);
			var_dump($_GET);
			echo '</pre>';
		}

		// Vérification de la durée de vie de la
		// session php
		if($this->portailUtils->getConnect()) {
			//portailUtils::sessionTimeout();
			$_SESSION['portail']['lastaction'] = time();
		}
       }
}
?>

include/portailUtils.php

[== PHP ==]
<?php
class portailUtils {

[...]
	public function getConnect() {
		global $plxMotor;

		if(isset($_SESSION['portail']) AND
			isset($_SESSION['portail']['logged']) AND
			$_SESSION['portail']['logged'] == true AND
			isset($_SESSION['portail']['ip'])) {
			// Désactivé dans le cas d'un dev sur docker AND $_SESSION['portail']['ip'] == $_SERVER['REMOTE_ADDR']) {
			return true;
		} else {
			return false;
		}
	}
}
?>

Du côté de portail.php j'ai besoin d'utiliser getConnect() mais pas moyen de l'appeler sans erreur

$__portailUtils->getConnect() ---> PHP Fatal error:  Call to a member function getConnect() on null in /var/www/html/plugins/portail/portail.php on line 72
$this->__portailUtils->getConnect() --> PHP Fatal error:  Call to a member function getConnect() on null in /var/www/html/plugins/portail/portail.php on line 72
$this->portailUtils->getConnect() ---> PHP Fatal error:  Call to a member function getConnect() on null in /var/www/html/plugins/portail/portail.php on line 72
$portailUtils->getConnect() ---> PHP Fatal error:  Call to a member function getConnect() on null in /var/www/html/plugins/portail/portail.php on line 72
$portail->getConnect() ---> PHP Fatal error:  Call to a member function getConnect() on null in /var/www/html/plugins/portail/portail.php on line 72
portailUtils::getConnect() ---> PHP Deprecated:  Non-static method portailUtils::getConnect() should not be called statically, assuming $this from incompatible context in /var/www/html/plugins/portail/portail.php on line 72

Dans le dernier ça passe avec de nouveau l'erreur de Deprecated. Là je suis arrivé au bout de mes connaissances en dev wink

Dernière modification par flipflip (07/12/2018 13:00:09)


"J'ai un string dans l'array" | http://www.blogoflip.fr

Hors ligne

#6 07/12/2018 12:50:35

Stéphane
Consultant PluXml
Lieu : pas loin de Toulouse
Inscription : 07/08/2007
Messages : 6 290
Site Web

Re : plugin, héritage de class

Salut

Tu appelles

$this->portailUtils->getConnect()

or $this->portailUtils n'est pas défini dans ta classe portail

tu as déclaré

$self->__portailUtils = new portailUtils();


Ancien responsable de PluXml  cool

Hors ligne

#7 07/12/2018 13:01:43

flipflip
Membre
Lieu : Lyon
Inscription : 19/05/2008
Messages : 768
Site Web

Re : plugin, héritage de class

Je viens de faire le test en appelant $self->__portailUtils->getConnect() mais même punition

PHP Fatal error:  Call to a member function getConnect() on null in /var/www/html/plugins/portail/portail.php on line 72


"J'ai un string dans l'array" | http://www.blogoflip.fr

Hors ligne

#8 07/12/2018 14:40:33

Stéphane
Consultant PluXml
Lieu : pas loin de Toulouse
Inscription : 07/08/2007
Messages : 6 290
Site Web

Re : plugin, héritage de class

et pourquoi $self->__portailUtils = new portailUtils(); et pas $this->__portailUtils = new portailUtils();


Ancien responsable de PluXml  cool

Hors ligne

#9 10/12/2018 12:50:07

flipflip
Membre
Lieu : Lyon
Inscription : 19/05/2008
Messages : 768
Site Web

Re : plugin, héritage de class

Merci Stéphane pour ta proposition, j'ai modifié le code en conséquence et ça marche... Enfin presque.

Maintenant depuis la class portail j'accède sans problème à portailUtils et portailAdv mais depuis portailsUtils je ne vois pas trop comment accéder à une fonction dans portailAdv.

Ci-dessous le code

portail.php

[== PHP ==]
<?php

defined('PLX_ROOT') or exit;

include __DIR__.'/include/portailUtils.php';
include __DIR__.'/include/portailAdv.php';

class portail extends plxPlugin {
	private $__portailUtils = false;
	private $__portailAdv = false;

	public function __construct($lang) {
		parent::__construct($lang);

		if(!class_exists('portailUtils')) { die('class portailUtils absent'); }
		$this->__portailUtils = new portailUtils();

		if(!class_exists('portailAdv')) { die('class portailAdv absent'); }
		$this->__portailAdv = new portailAdv();
	}
}

Rien de particulier pour les class portailUtils et portailAdv.


"J'ai un string dans l'array" | http://www.blogoflip.fr

Hors ligne

#10 Aujourd'hui 02:16:26

Jerry Wham
Membre
Inscription : 13/07/2011
Messages : 2 560
Site Web

Re : plugin, héritage de class

Je te conseille de lire le blog de Tom Butler (https://r.je).
Pour ce qui te concerne, il faudrait utiliser les namespaces, et un autoloader...


Mangez un castor, vous sauverez un arbre !

J'ai la tête dans le  ...code

Hors ligne

Pied de page des forums

A propos Nous soutenir Contact Twitter Google+
Copyright © 2006-2018 PluXml.org, tous droits réservés