Kdyby\Events aneb $this->breforeDelete(…) – Call to undefined function

theacastus
Člen | 81
+
0
-

Zdravím,

v databázi mám mezi s sebou navázané různé věci a potřebuji aby se něco smazalo před tím, než se začne mazat v tabulkce příslušného manageru/fasády.

Chtěl jsem použít eventy, ale asi si s nimi ještě úplně nerozumím.

Mám listener:

<?php
namespace App\Model\Listeners;

use App\Model\Managers\EmailManager;
use Kdyby\Events\Subscriber;

class EmailServiceListener implements Subscriber
{
	//... nejaky kod

    /**
     * @return array
     */
    public function getSubscribedEvents()
    {
        return [
            'App\Model\Managers\HostingManager::beforeDelete'   => 'beforeDeleteHosting',
        ];
    }

    public function beforeDeleteHosting($hosting, $userId)
    {
        $userDomains = $this->emailManager->getUserEmailDomains($userId);

        foreach ($userDomains as $userDomain)
        {
            if ($userDomain['domain'] == $hosting['domain_name'])
            {
                $domainId = $userDomain['id'];
				break;
            }
        }

        if (!isset($domainId))
            return;

        $this->emailManager->deleteEmailDomain($userId, $domainId);
    }
}

A v konkrétním manageru jej volám:

<?php
namespace App\Model\Managers;

use App\Model\Exceptions\HostingManagerException;
use App\Model\PackageManager;
use App\Model\UserManager;
use Nette\Database\Context;
use Nette\SmartObject;

/**
 * Class HostingManager
 * @package App\Model\Managers
 */
class HostingManager
{
    use SmartObject;

    public $onAdd  = [];

    public $onEdit = [];

    public $beforeDelete = [];
    public $onDelete = [];

    /**
     * @var Context
     */
    private $db;

    const
        TARIFF_TABLE    = 'tarif_hosting',
        DOMAIN_TABLE    = 'domain';

    /**
     * EmailManager constructor.
     * @param Context $context
     * @param UserManager $userManager
     */
    public function __construct(
        Context $context,
        UserManager $userManager
    )
    {
        $this->db               = $context;
        $this->userManager      = $userManager;
    }

	// ... nejaky kod

    /**
     * @param int $userId
     * @param int $hostingId
     * @throws HostingManagerException
     */
    public function deleteHosting($userId, $hostingId)
    {
        $hosting = $this->getHosting($userId, $hostingId);

        if(!$hosting)
            throw new HostingManagerException('Hosting neexistuje nebo nepatří tomuto uživateli.');

        $this->beforeDelete($this, $hosting, $userId);

        $this->db->table(self::TARIFF_TABLE)
            ->where('id', $hostingId)
            ->delete();

        $this->onDelete($this, $hosting, $userId);
    }
}

S Kdyby\events začínám, jestli mi tam chybí EventDispatcher/EventManager… nikde jsem nenašel příklad (třeba jednoduchá aplikace) která to má okomentované :/

Díky

CZechBoY
Člen | 3608
+
0
-

jo, předej si EventManager do té HostingManager třídy a pak zavolej $this->eventManager->dispatch(nazev eventu, parametry)

viz https://github.com/…/en/index.md#…

David Matějka
Moderator | 6445
+
0
-

nette eventy museji zacinat na on, takze onBeforeDelete

Kori
Člen | 73
+
0
-
  1. viz co pise David
  2. Listener si zaregistruj jako sluzbu s tagem [kdyby.subscriber], pak nepotrebujes EventManager a dispatchovat eventy manualne. Viz dokumentace.
  3. Podle kodu si predavas pres event 3 parametry, metoda beforeDeleteHosting() ale ocekava dva. Tj., oprav na:
$this->onBeforeDelete($hosting, $userId);
theacastus
Člen | 81
+
0
-

Kori napsal(a):

  1. viz co pise David
  2. Listener si zaregistruj jako sluzbu s tagem [kdyby.subscriber], pak nepotrebujes EventManager a dispatchovat eventy manualne. Viz dokumentace.
  3. Podle kodu si predavas pres event 3 parametry, metoda beforeDeleteHosting() ale ocekava dva. Tj., oprav na:
$this->onBeforeDelete($hosting, $userId);

Áha a k čemu se tedy u eventů v příkladech předává $this, například

class SomeClass {
	public $onEvent = [];

	public function someFunction()
	{
		$this->onEvent($this);
	}
}

Nikde jsem to neviděl?

U různých getterů/setterů to je kvůli řetězení do $this->doSomething()->doSomethingElse();

Editoval theacastus (20. 2. 2018 17:42)

David Matějka
Moderator | 6445
+
0
-

nemusi se to predavat, ale je to takovy zvyk, ze se jako privni parametr dava ten objekt, ktery udalost vyvolal

theacastus
Člen | 81
+
0
-

David Matějka napsal(a):

nemusi se to predavat, ale je to takovy zvyk, ze se jako privni parametr dava ten objekt, ktery udalost vyvolal

A má to nějaké praktické odůvodnění, proč se to dělá ? Při debuggingu bych asi něco vymyslel na produkci mě ale nic nenapadá – tohle už je jen má zvědavost, než cokoliv jiného.

Kori
Člen | 73
+
0
-

Osobne predavam jen to, co potrebuju, $this jen kdyz se dal s tim objektem pracuje. Ale je to o zvyku, jak uz zaznelo.

CZechBoY
Člen | 3608
+
0
-

David Matějka napsal(a):

nette eventy museji zacinat na on, takze onBeforeDelete

Ale on používá Kdyby/Events, to platí taky?

theacastus
Člen | 81
+
+1
-

CZechBoY napsal(a):

David Matějka napsal(a):

nette eventy museji zacinat na on, takze onBeforeDelete

Ale on používá Kdyby/Events, to platí taky?

Přidání on pomohlo – asi pro to že kdyby\events pracuje i s nette eventy, které si samo dispatchuje voláním promněné eventu.

Kdybych chtěl beforeDelete tak bych musel použít EventManager a event si dispatchnout přímo asi (jak již bylo řečeno).

Myslím že z dokumentace kdyby\events tak nějak nepřímo vyplývá že umí pracovat s nette eventy a není třeba je dispatchovat. A protože to je nette event, musí mít předponu on.

To si myslím, ale hlubší průzkum bude později :D

Díky moc všem :-)