redbitcz / vyfakturuj-api-php

PHP knihovna pro Vyfakturuj API
https://www.vyfakturuj.cz/api/
MIT License
2 stars 1 forks source link

Dvojité require ve wordpressu způsobuje fatal error #2

Closed pavel-janicek closed 6 years ago

pavel-janicek commented 6 years ago

Zkusil jsem ve svém pluginu tento přístup:

if(!class_exists(VyfakturujAPI)){
          require_once('lib/vyfakturuj-api/VyfakturujAPI.class.php');
}

Při pokusu o aktivaci mého pluginu mi wordpress hlásí:

Fatal error: Cannot declare class VyfakturujAPI, because the name is already in use in (mojedomena)/wp-content/plugins/simpleshop-wpplugin-v1.3.1/lib/vyfakturuj-api/VyfakturujAPI.class.php on line 9

Nejbezpečnější by asi bylo třídu Vyfakturuj API deklarovat jenom jednou

jakubboucek commented 6 years ago

Ahoj Pavle, koukám na to a není mi úplně jasné, za jakých okolností problém nastane.

Potřeboval bych vědět další informace:

  1. Kromě SimpleShop pluginu, máš ve Wordpressu ještě něco jiného, co si natahuje tu knihovnu?
  2. Do jakého místa jsi zadal ten kód if(!class_exists(VyfakturujAPI)){, který popisuješ na začátku tohoto Issue?
pavel-janicek commented 6 years ago

Zkusím popsat přesněji. Na Wordpressu mám svůj plugin, u kterého hodlám využívat API vyfakturuj. A současně je tam nainstalovaný SimpleShop plugin verze 1.3.1

Simpleshop plugin také používá Vyfakturuj API pro načtení produktů ze Simpleshopu:

/**
     * Get products from simple shop via API
     */
    function wp_ajax_load_simple_shop_products(){
        $ssc = new SSC();

        $values = array();
        if($ssc->email && $ssc->secure_key){
            $vyfakturuj_api = new \VyfakturujAPI($ssc->email,$ssc->secure_key);
            $ret = $vyfakturuj_api->getProducts();

            if($ret){
                foreach($ret as $product){
                    $values[$product['code']] = $product['name'];
                }
            }
        }
        echo json_encode($values);
        exit();
    }

k tomu potřebuje class VyfakturujAPI která je v pluginu na relativní cestě lib/vyfakturuj-api/VyfakturujAPI.class.php

Můj plugin také potřebuje VyfakturujAPI pro získání faktur:

$vyfakturuj_api = new VyfakturujAPI("info@mywii.cz","secret_key");
$id = $_GET['obj'];
$ret = $vyfakturuj_api->getInvoice($id);

V momentě, kdy chci použít třídu VyfakturujAPI ve svém pluginu, tak dostávám chybu Fatal error: Cannot declare class VyfakturujAPI, because the name is already in use in (mojedomena)/wp-content/plugins/simpleshop-wpplugin-v1.3.1/lib/vyfakturuj-api/VyfakturujAPI.class.php on line 9

Zatím jsem to ve svém pluginu vyřešil tak, že jsem třídu VyfakturujAPI ve svém pluginu přejmenoval

Myslím si ale, že obecné řešení by bylo zajistit v rámci PHP souboru, aby se třída VyfakturujAPI deklarovala jenom jednou. Proto to PR.

jakubboucek commented 6 years ago

Aha, chápu.

Pak sedy pojďme podívat, kde se volá načítání té knihovny. Problém totiž není v tom, že se někde volá $vyfakturuj_api = new VyfakturujAPI(...), ale že je někde voláno require(lib/vyfakturuj-api/VyfakturujAPI.class.php) *). Přesněji řečeno takový kód je v aplikaci 2x.

A právě tam se musí oprava provést – tam je totiž příčina chyby.

Správnou cestou integrace knihoven do kódu je přes Composer – ten přesně takové věci řeší. Jak to má Wordpress, to vlastně nevím. Zkusím se dopátrat, jak to dělá ten plugin do Wordpressu.

Jak sis do Wordpressu nainstaloval tu původní verzi knihovny pro Vyfakturuj?

*) Nemusí to být require(...), ale třeba i include(...), require_once(...), či include_once(...);

pavel-janicek commented 6 years ago

Plugin si právě instaluji tak, že otrocky stáhnu api class odsud (tento repozitář) a ve svém pluginu jsem jej umístil do libs/VyfakturujAPI.class.php.

Můj plugin je třída, která na __construct mimo jiné volá:

require_once("libs/VyfakturujAPI.class.php");

Zkoušel jsem toto obejít právě tím, že jsem na constructoru své třídy toto obalil na:

if(!class_exists(VyfakturujAPI)){
          require_once("libs/VyfakturujAPI.class.php");
}

A to se Wordpressu stále nelíbilo. Takže jsem ve svém pluginu class VyfakturujAPI přejmenoval na class class PavelVyfakturujAPI a později v kódu volám $vyfakturuj_api = new PavelVyfakturujAPI("info@mywii.cz","secret_key");

Možná to bude tím, že Simpleshop plugin používá vlastní, osekanou verzi VyfakturujAPI, která v zásadě umí jenom stáhnout produkty.

jakubboucek commented 6 years ago

Výborně. Myslím, že už mám všechny potřebné informace. Diky! Nyní se pustím do práce a zkusím to opravit co nejdříve.