Fuck me, to było banalnie proste, a ja tak kuczyłem :)


Autoloader załatwia fajnie sprawę.
Poniżej kawałek moich wypocin, oceńcie proszę to koszerne, czy do kosza ;D



Przykładowy moduł:

<?php

$layout['pagetitle'] = trans('Redirector list');

$PLUGIN = new RedirectorsPlugin($LMS);


$redirector_list = $PLUGIN->GetRedirectorList();

$SESSION->save('backto', $_SERVER['QUERY_STRING']);

$SMARTY->assign('redirector_list',$redirector_list);
$SMARTY->display('redirectorlist.html');

?>

Przykładowy plugin:

<?php

/*
 *  LMS version 1.11-git
 *
 *  Copyright (C) 2001-2013 LMS Developers
 *
 *  Please, see the doc/AUTHORS for more information about authors!
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License Version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
 *  USA.
 *
 *  $Id$
 */

/**
 * PluginExample
 *
 * @author Maciej Lew <maciej.lew.1987@gmail.com>
 */
class RedirectorsPlugin extends LMSPlugin
{

    public $LMS;

    public function __construct(&$LMS)
    {
        $this->LMS = &$LMS;
        $this->registerHandlers();
    }

//first things first
    public function registerHandlers()
    {
        $this->handlers = array(
            'menu_initialized' => array(
                'class' => 'PluginMenuHandler',
                'method' => 'drawMenu'
            ),
            'modules_dir_initialized' => array(
                'class' => 'PluginDirHandler',
                'method' => 'addModulesDir'
            ),
            'smarty_initialized' => array(
                'class' => 'PluginDirHandler',
                'method' => 'addTemplatesDir'
            ),
            'lms_initialized' => array(
                'class' => 'PluginMethodsHandler',
                'method' => 'addPluginMethods'
            ),
        );
    }

//define plugin methods here

        public function DeleteRedirector($id)
        {
                return $this->LMS->DB->Execute('DELETE FROM _redirectors WHERE id=?', array($id));
        }


    public function GetRedirectorList() {
        $retval = array();
        $idx = 0;
        $redirector_list = $this->LMS->DB->GetAll('SELECT r.id id, r.enabled redirector_enabled, name, duration, period, message, (SELECT COUNT(n.id) FROM _redirectorassignments ra, nodes n WHERE n.id = ra.node_id AND ra.redirector_id = r.id AND n.warning=1 ) enabled, target_url, (SELECT COUNT(id) FROM _redirectorassignments ra WHERE ra.redirector_id = r.id) `set` FROM _redirectors r');
        if (!$redirector_list) {
        return false;
        }
        foreach ($redirector_list as $redirector) {
        $redirector['active'] = count($this->GetRedirectorAffectedCustomers($redirector['id']));
        $retval[$idx++] = $redirector;
        }
        return $retval;
    }

    public function GetRedirector($id) {
        return $this->LMS->DB->GetRow('SELECT id, name, duration, period, block_traffic, interactive, enabled, append_customer_message, message, target_url, trigger_min, trigger_max, last_payment_min, last_payment_max, last_liability_min, last_liability_max, skip_addresslist FROM _redirectors WHERE id = ?', array($id));
    }


(...)

}

?>



Pozdrawiam.

W dniu 5 lutego 2015 19:22 użytkownik Przemysław Kudyba <zlyzwierz@gmail.com> napisał:
Wygląda rozsądnie - popróbuję.

A może macie jakieś inne pomysły jak bezboleśnie rozszerzać LMS-a nie tykając jego kodu ?

W dniu 5 lutego 2015 19:09 użytkownik Maciej Lew <maciej.lew.1987@gmail.com> napisał:

Jeśli musisz mieć te metody w klasie RedirectorsPlugin użyj wzorca Singleton:

class RedirectorsPlugin extends LMSPlugin
{
    private static $instance;

    public function __construct()
    {
        parent::__construct();
        self::$instance = $this;
    }

    public static function getInstance()
    {
        return self::$instance;
    }

    // cała reszta metod

}

W kodzie wtedy robisz:
$plugin = RedirectorsPlugin::getInstance();
$plugin->mojaMetoda($xyz);

Nie testowałem tego ale powinno działać ;) Rozwiązanie to ma ten minus że nie będzie dobrze działało dla włączonych kilku instancji tego samego pluginu.


W dniu 05.02.2015 o 10:34, Przemysław Kudyba pisze:
Mam moduły fizycznie w katalogu z pluginem - takie same jak są w modules. Korzystając z odpowiednich hooków dodaję ścieżki, żeby LMS wiedział gdzie szukać modułów i szablonów.

Wszystko jest ok,  wszystko do tego momentu działa, zamysł jest taki, żeby dodać jakąś funkcjonalność do LMS i jednocześnie nie dotykać jego kodu. Chciałbym użyć jakichś swoich metod które zdefiniowane byłyby w jakiejś klasie z pluginem.

Problem w tym, że wywołując nowy moduł, który powołałem do zycia z pozimu pluginu - nie mam dostępu do samej klasy z pluginem :)

Przydałoby się mieć coś takiego:

$PLUGIN = $LMS->getPluginInstance('RedirectorsPlugin');

żeby w kodzie dodatkowego modułu zrobić już jak biały człowiek:

$PLUGIN->mojaMetoda(xyz);


Poniżej najważniejsze kawałki kodu w pluginie:


class RedirectorsPlugin extends LMSPlugin
{
    public function registerHandlers()
    {
        $this->handlers = array(
            'menu_initialized' => array(
                'class' => 'PluginMenuHandler',
                'method' => 'drawMenu'
            ),
            'modules_dir_initialized' => array(
                'class' => 'PluginDirHandler',
                'method' => 'addModulesDir'
            ),
            'smarty_initialized' => array(
                'class' => 'PluginDirHandler',
                'method' => 'addTemplatesDir'
            ),
            'lms_initialized' => array(
                'class' => 'PluginMethodsHandler',
                'method' => 'addPluginMethods'    <==== tutaj próbowałem coś rzeźbić, ale bez efektów.
            ),
        );
    }
}



class PluginMenuHandler
{
    /**
     * Example handler that does nothing
     *
     * @param mixed $hook_data
     */
    public function drawMenu($hook_data)
    {
        error_log("Genereting menu for redirectors");
        $hook_data["redirectors"] =  array(
                        "name" => trans("Customer messages"),
                        "img" => "../plugins/RedirectorsPlugin/img/user_comment.png",
                        "link" => "?m=customermessages",
                        "tip" => trans("User customer messges"),
                        "accesskey" => "z",
                        "prio" => "9",
                        "submenu" => array(
                                array(
                                        "name" => trans("Redirector list"),
                                        "link" => "?m=redirectorlist",
                                        "tip" => trans("Redirector list"),
                                        "prio" => 10
                                ),
                                array(
                                        "name" => trans("New redirector"),
                                        "link" => "?m=redirectoradd",
                                        "tip" => trans("Add new redirector"),
                                        "prio" => 20
                                )
                        ));

        return $hook_data;
    }
}



class PluginDirHandler
{
    /**
     * Example handler that does nothing
     *
     * @param mixed $hook_data
     */
    public function addModulesDir($hook_data)
    {
        error_log("Adding modules directory for RedirectorsPlugin");
        array_push($hook_data,SYS_DIR . "/plugins/RedirectorsPlugin/modules/");

        return $hook_data;
    }

    public function addTemplatesDir($hook_data)
    {
        error_log("Adding modules directory for RedirectorsPlugin");
        $hook_data->AddTemplateDir(SYS_DIR . "/plugins/RedirectorsPlugin/templates/");

        //return $hook_data;
    }
}


Więc podsumowując - na mój chłopski rozum - najbardziej urządzałoby mnie pobranie instancji klasy pluginu z poziomu $LMS i juz dalsza praca na niej. Czy jest to w miarę sensowne rozwiązanie ?


Pozdrawiam.

W dniu 4 lutego 2015 18:59 użytkownik Maciej Lew <maciej.lew.1987@gmail.com> napisał:
Chyba nie da się tego zrobić w taki sposób jak chcesz to zrobić.

Od pewnego czasu LMS ma autoloader więc można osiągnąć podobny efekt na kilka innych sposobów:

1. Zrobić własną klasę dziedziczącą po LMS i w niej dodać swoją nową metodę lub metodę przesłaniającą obecnie dostępną:

class MyLMS extends LMS
{
    public function myMethod()
   {
        echo 'myMethod';
    }
}

2. Dodać zupełnie oderwaną od klasy LMS nową klasę

class MyClass
{
    public function myMethod()
   {
        echo 'myMethod';
    }
}

3. Jeśli chodzi o przesłonięcie istniejącej metody z LMS to można w większości przypadków dodać własnego "managera":

class MyFinanceManager extends LMSFinanceManager implements LMSFinanceManagerInterface
{

    public function GetCustomerAssignments($id, $show_expired = false)
    {
        $assignments = parent::GetCustomerAssignments($id, $show_expired);
        // tu robimy coś na zmiennej $assignment i zwracamy zmodyfikowaną
        return $assignments;
    }
}

// rejestrujemy nowego managera
$LMS->setFinanaceManager(new MyFinanceManager($LMS->getDb(), $LMS>getAuth(), $LMS->getCache(), $LMS->getSyslog()));

Dzięki autoloaderowi klasy MyLMS, MyClass i MyFinanceManager powinny być widoczne z innych pluginów (choć trzeba by było dorobić sobie sprawdzanie czy tak na pewno jest, czy ktoś nie wyłączył pluginu od którego zależy działanie naszego pluginu).

W dniu 03.02.2015 o 11:52, Przemysław Kudyba pisze:

Witam.

Przerabiam dodatki do LMS-a które jakiś czas temu nakodziłem, żeby robiły użytek z nowego stystemu pluginów w LMS.
Mam w związku z tym pytanko:  jak dorzucić z poziomu pluginu jakieś swoje metody do klasy LMS (a raczej instancji) tak, żeby były wydoczne dla funkcji spoza pluginu i możba było ich używać np. w innych pluginach ?

Pozdrawiam