Giter Site home page Giter Site logo

skautis's People

Contributors

jindrichpilar avatar johnymachine avatar marekdedic avatar misakstvanu avatar sinacek avatar xificurk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

skautis's Issues

Nahrazení SoapClient za nějakou rozumnější abstrakci

Rád bych navrhl pro verzi 3.0 výměnu Soap klienta. Je to něco, co minimálně ve svých projektech mám v plánu dělat, a tedy nabízím implementaci přímo tady. Rád bych využil buď Guzzle/PSR-7 (osobně mi přijde z uživatelského pohledu jednodušší mít závislost přímo na Guzzle), nebo např. meng-tian/async-soap-guzzle

Motivace

  • Bylo by možné zpřístupnit async API (což jestli dobře chápu byla hlavní motivace pro #29)
  • Jednodušší testování - ve Skautském Hospodaření mockujeme Soap komunikaci přes PHP-VCR, pro Guzzle je mnohem jednodušší testy psát (jsou tam přímo utility middlewares jako HistoryMiddleware apod). Kromě toho některé části ani nejdou namockovat (SoapClient při vytvoření instance stahuje wsdl soubor, což není možné nijak přetížit).
  • V skautis/nette nebudeme muset mít vlastní panel pro Tracy - bude fungovat jakýkoliv panel pro Guzzle (např. https://github.com/contributte/guzzlette)
    Nemám problém to připravit a poslat PR, ale zajímal by mě ohlas na podobnou změnu.

Update PHP

Navrhuji zvednout verzi na PHP 7.X. Pro kompatibilitu by bylo nejlepsi 7.0, ale 7.1 ma z meho pohledu znacne zlepseni (nullable, void, iterable typehinty)

  • Type hints
  • Return type hints
  • Iterators (+typehint)

Skrytá zbytečná závislost na Dibi

Třída \SkautIS\Nette\Tracy\Panel dědí z \DibiObject, což je skrytá závislost na Dibi, která není uvedena v composer.json.

Nicméně je to zřejmě jediná závislost na Dibi, navíc celkem zbytečná. Stačilo by místo \DibiObject použít \Nette\Object a mělo by to být v cajku.

Coding style

Jelikoz se codebase rozrusta, je potreba rozhodnout o cofing style. Idealne mit i config pro PHP Code Sniffer / PHP Code Fixer.

Projekty pro urcity framework by meli pouzivat veci zabehle pro dany framework, takze se jedna hlavne o samostatnou knihovnu.

Krome stylu psani je potreba rozhodnout i o jednotnem pojmenovani.
Napriklad:
ISessionAdapter vs SessionAdapterInterface
ASessionAdapter vs AbstractSessionAdapter

Jako vyhodu delsiho zapisu vidim ze kazdy to muze precist bez znalosti toho prefixovani pismenem. Take mi prijde v PHP komunite rozsirenejsi (Symfony, Zend 2)

Nejlehci by bylo prevzit to od nejakeho projektu, jelikoz bychom nemuseli sepisovat pravidla a vytvaret config pro PHP Code Sniffer.

Takhle vypadaji nejake statistiky vuci PSR2.

setInit

V nápovědě se píše o funkci setInit, ale nikde jsem ji nedohledal...

Nevhodně se chovajíci isMaintenance při nenalezení domeny

Když se pokusí isMaintenance získat headery Skautisu a serveru se nepodaří DNS lookup tak hodí warning:

Warning: get_headers(): php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution

Což podle toho jak aplikace řeší warningy může znamenat že se bude ignorovat, nebo třeba že se bude považovat za error a aplikace vrátí "Něco se rozbilo" místo toho aby prostě vypnula Skautis funkce a dál fungovala.
Osobně nechápu proč je tohle řešeno přes warning a ne exception.

Možné řešení:

        set_error_handler(function() {});
        $headers = get_headers($this->getWebServiceUrl("UserManagement"));
        restore_error_handler();

        return !is_array($headers) || !in_array('HTTP/1.1 200 OK', $headers);

To je nejsnazší, v případě problému se bude trvářit že Skautis je v údržbě a zbytek aplikace bude fungovat dál. Ale ztratí se informace co nešlo (DNS lookup) a metoda isMaintanance checkuje i něco co chekovat nemá.

Samozřejmě by šlo to transformovat do exceptionu což je o něco lepší, protože se dají hromadně chytat skautis exceptiony. Ale pořád je to nicmoc použití. Obzvláště když napojení na skautis je vedlejší funkcionalita a tedy to že se nelze připojit není problém ale je to potřeba vědět.

Př:

try {
  if (!$this->skautis->isMaintanance() {
    $this->updateUserInfoFromSkautis();
  }
}
catch (\Skautis\Exception $e) {
  //ignore nebo log
}

$this->displaySomePage();

Session Storage problem

Ahoj,

dostal jsem se do faze kdy potrebuji vyresit tento problem, ktery jsem uz nejakou dobu odkladal. Bohuzel nedari se mi prijit na elegantni zpusob se zachovanim zpetne kompatibility.

$this->perStorage ma z dob kdy tahle knihovna byla soucasti nejakeho Nette projektu par neuplne peknych vlastnosti.
Ktere se spoustou popularnich tropi problemy, protoze nepouzivaji magicke metody. (Symfony, Laravel, CodeIgniter, CakePHP, FuelPHP, Aura) [alespon podle skouknuti dokumentace dokumentace]

Pristup k nedefinovanym promenym a spolehani se na PHP ze z nich automaticky udela pole.
Kod

Zpusob jakym aplikace pracuje se session vubec nemusi mit z defaultni PHP session nic spolecneho.
Kod

Navrhovane reseni:
Vytvori se trida pro konfiguraci, ktera klidne muze implementovat ArrayAccess, ale has(),get(),set() by bylo vhodnejsi. Ta trida bude implementovat Serializable interface.

Misto session dostane SkautIS SessionAdapter s metodou store('nazev', $object) a retrieve('nazev'). A s pomoci teto tridy vse ulozit v __destruct() metode. A naopak pri __construct() nacist.

Kdyz by se nejake zakladni adaptery pribalily do knihovny (pro $_SESSION a NETTE session treba) byly by nutne zmeny v kodu pro uzivatele knihovny minimalni.
Misto:

$storage = \Nette\Environment::getSession()->getSection("__" . __CLASS__);
$this->context->skautIS->setStorage($storage, TRUE);

By bylo

$section = \Nette\Environment::getSession()->getSection("__" . __CLASS__);
$storage = new \SkautIS\SessionAdapter\NetteAdapter($section);
$this->context->skautIS->setStorage($storage, TRUE);

Misto

$skautis = \SkautIS\SkautIS::getInstance()

By bylo

$skautis = \SkautIS\SkautIS::getInstance()
$storage = new \SkautIS\SessionAdapter\SessionAdapter();
$skautis->setStorage($storage);

Pres konfiguracni objekt je to vhodnejsi nez pristupovat primo k SessionAdapteru, protoze nektere implementace podporuji sekce a jine odlisnosti.

Reseni rad implementuji, ale nechtel jsem se do toho postet pred nejakou diskusi kdyz to neni zpetne kompatibilni.

BaseException

Mohu se zeptat co je za třídu BaseException?

A druhy dotaz. K čemu má sloužit funkce setStorage?

CacheDecorator pro WebService

Ve vetsi aplikaci, nebo aplikaci hodne modulovane (pouzivajici framework) se casto stava ze se vola nektera funkce nekolikrat a diky slozeni z jednotlivych komponent je ponekud slozitejsi si jiz prenesena data predavat.

Priklad:

  • Login //Taha data
  • Event onLoggedIn - aktualizuj udaje pro prihlaseneho uzivatele //Taha data
  • Dlouho nebyl aktualizovan seznam vedoucich //Taha data
  • Panel na na boku stranky (samostatny plugin) //Taha data
  • Controller //Taha data

Prvni request bude trvat 150ms+ (stazeni wsdl)
Kazdy dalsi 60ms+
Coz dohromady dava 390ms misto 150.
Samozrejme za predpokladu ze je dobre pripojeni, Skautis je nezatizeny a slape rychle.

Coz samo o sobe neni prilis dlouho, ale kdyz se k tomu pricte prace DB, nejake to sahnuti na soubory v kombinaci s mobilnim pripojeni a programatorem zacatecnikem (nebo nemajicim cas optimalizovat) je z toho par sekundovy pozadavek, coz uz je problem.

Navrhoval bych pouziti cache pro jiz prenesena data, podobne jako maji ruzna ORM. Tak aby WebService pri stejnych requestech vracela odpoved z cache.

Implementaci bych navrhl pomoci decorator paternu, aby se dala tato funkce jednoduse pridat a jinak neprekazela.

V knihovne by meli existovat 2 predpripravene Cache implementace

  • Array - pro 1 beh PHP
  • Session - po dobu session (Vyuzivajici jiz existujici SessionAdapterInterface)

Otazky ktere je potreba prvni zodpovedet:

  • Patri to jeste do knihovny?
  • Jak by to fungovalo s batch requesty issue #29?
  • Mela by se vytvorit WebServiceInterface, zrusit dedeni od \SoapClient a ten pouzit interne?
  • Vhodny zpusob vytvoreni klice.
  • Bezpecnost, jak nevracet data neopravnenemu uzivateli (spolehlive) - spolehat se ze uzivatel zavola odhlasovaci metodu / vyzadovat alespon jeden uspesny pozadavek na Skautis?

Ukazka

class WebServiceCacheDecorator implements WebServiceInterface
{

   /**
     * @var Skautis\Wsdl\WebService
     */
   protected $webService;

   /**
    * @var Skautis\CacheInterface
    */
   protected $cache;

   public function __get($functionName, $args)
   {
      if (isset($args['skautis_cache']) && $args['skautis_cache'] === false) {
          unset($args['skautis_cache']);
          return parent::__get($functionName, $args);
      }

      $sargs = $args; 
      ksort($sargs); 
      $jsonArgs = json_encode($sargs);

      $hash = hash($functionName . $jsonArgs);

      if ($this->cache->has($hash)) {
          return $this->cache->get($hash);
      }
      else {
          return parent::__get($functionName, $args);
      }
   }
}

composer package

Ahoj,

navrhuji doplnit možnost instalace pomocí composer + packagist (http://getcomposer.org/)

Velmi usnadňuje práci se závislostmi + class autoloading.
Je velmi využívaný např.: Drupal (8), phpBB, a naprostá většina frameworků Nette, Symfony, Zend, Laravel..

Pokud by o to byl zájem, rád to udělám a hodím pull request.

Chyba parseOutput

Ve verzi 3.0.0 alpha 1 je problém s parsováním output, pokud neobsahuje tag <...Output> - např.:

Undefined property: stdClass::$UserDetailOutput

Další problém je v typu, pokud se vrací $result (stdClass místo array)

...
$output = $result->{$fname . 'Output'};
if (!isset($output)) {
    return $result; //neobsahuje $fname.Output
}
...

Použití magických metod (`Skautis::__get()`) znemožňuje statickou analýzu

Ahoj,
vzhledem k tomu, že vidím práci na verzi 3.0 bych chtěl navrhnout ke zvážení používání "magických" metod, konkrétně Skautis::__get(). Já jsem na to konkrétně narazil v případě statické analýzy kódu, která je při použítí __get() prakticky nemožná. Navíc mi obecně přijde, že to je spíš "code smell" a s verzí 3.0 může být jedinečná šance to změnit...

Pokud byste o tom uvažovali, rád se budu bavit o alternativách a případně pak udělám PR. Díky!

Chybí example usecase

Mohl bys prosím doplnit nějaký ukázkový usecase? Třeba do /README.rst, pak se to hezky ukazuje při otevření repa. :-) Mně osobně jde pouze o přihlášení uživatele a vypsání jeho Person.

Dík

Jméno balíčku a namespace

Jelikož se pomalu hromadí projekty na github.com/skaut. Bylo by dobré mít věci přehledné.
Dobrým začátkem by bylo mít společené root namespace skaut.

Současný stav

Repozirář Baliček Kvalifikovaná hlavní třída
skaut/Skautis skautis/skautis Skautis\Skautis

Navrhovaný stav

Repozirář Baliček Kvalifikovaná hlavní třída
skaut/skautis skaut/skautis Skaut\Skautis

Notice: Array to string conversion as WS.php:92

Verze systémů:

  • SkautIS - forr z repo dne 22.12.2014
  • Nette - 2.2.3 revize 2014-08-28

Popis problému:
Snažím se rozjet SkautIS podle dokumentace (co jsem kde poshrabával místama), avšak narážím na následující problém při použití tohoto kusu kódu z readme.md:

$data = $skautis->user->UserDetail(array("ID"=>1940));

Vyhodí to v Nette vyjímku :"Notice: Array to string conversion as WS.php:92"

Kód okolo toho:

class SkautisPresenter extends BasePresenter
{
    /** @var  \SkautIS\SkautIS */
    protected $skautIS;

    /**
     * Injects connection to IS skaut
     *
     * @param \SkautIS\SkautIS $skautIS
     * @throws \Nette\InvalidStateException
     */
    public function injectEvent(\SkautIS\SkautIS $skautIS){
        if ($this->skautIS) {
            throw new \Nette\InvalidStateException('SkautIS has already been set');
        }
        $this->skautIS = $skautIS;
    }

    public function actionDefault(){
        $request = $this->request;
        if ($request->getPost('skautIS_Token')
            && $request->getPost('skautIS_IDRole')
            && $request->getPost('skautIS_IDUnit')
        ){
            $this->skautIS->setLoginData($request->getPost('skautIS_Token')
                ,$request->getPost('skautIS_IDRole')
                ,$request->getPost('skautIS_IDUnit'));
        } elseif ($this->skautIS->isLoggedIn()){
            $this->skautIS->updateLogoutTime();
        } else {
            $this->redirect('login');
        }
    }

    public function renderDefault(){
        $this->skautIS->getWsdlList();
        $this->template->person = $this->skautIS->user->UserDetail(array("ID"=>1940));
    }
    /**
     * Sets variable for view of "Default" page
     */
    public function renderLogin()
    {
        $this->template->loginUrl = $this->skautIS->getLoginUrl();
    }

Účelem je vážně jen nějaké řešení, které začne tahat opravdová data, abych se měl od čeho odpíchnout.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.