Skip to content

Commit

Permalink
Merge pull request nextcloud#20597 from nextcloud/enh/lazy_node_events
Browse files Browse the repository at this point in the history
Add lazy events for the Node API
  • Loading branch information
rullzer authored May 28, 2020
2 parents 77c1aeb + 6aa6ab3 commit b638c6e
Show file tree
Hide file tree
Showing 21 changed files with 753 additions and 63 deletions.
1 change: 1 addition & 0 deletions lib/base.php
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ public static function init() {

// setup the basic server
self::$server = new \OC\Server(\OC::$WEBROOT, self::$config);
self::$server->boot();
\OC::$server->getEventLogger()->log('autoloader', 'Autoloader', $loaderStart, $loaderEnd);
\OC::$server->getEventLogger()->start('boot', 'Initialize');

Expand Down
15 changes: 15 additions & 0 deletions lib/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,21 @@
'OCP\\Files\\Events\\FolderScannedEvent' => $baseDir . '/lib/public/Files/Events/FolderScannedEvent.php',
'OCP\\Files\\Events\\NodeAddedToCache' => $baseDir . '/lib/public/Files/Events/NodeAddedToCache.php',
'OCP\\Files\\Events\\NodeRemovedFromCache' => $baseDir . '/lib/public/Files/Events/NodeRemovedFromCache.php',
'OCP\\Files\\Events\\Node\\AbstractNodeEvent' => $baseDir . '/lib/public/Files/Events/Node/AbstractNodeEvent.php',
'OCP\\Files\\Events\\Node\\AbstractNodesEvent' => $baseDir . '/lib/public/Files/Events/Node/AbstractNodesEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeCopiedEvent' => $baseDir . '/lib/public/Files/Events/Node/BeforeNodeCopiedEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeCreatedEvent' => $baseDir . '/lib/public/Files/Events/Node/BeforeNodeCreatedEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeDeletedEvent' => $baseDir . '/lib/public/Files/Events/Node/BeforeNodeDeletedEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeReadEvent' => $baseDir . '/lib/public/Files/Events/Node/BeforeNodeReadEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeRenamedEvent' => $baseDir . '/lib/public/Files/Events/Node/BeforeNodeRenamedEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeTouchedEvent' => $baseDir . '/lib/public/Files/Events/Node/BeforeNodeTouchedEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeWrittenEvent' => $baseDir . '/lib/public/Files/Events/Node/BeforeNodeWrittenEvent.php',
'OCP\\Files\\Events\\Node\\NodeCopiedEvent' => $baseDir . '/lib/public/Files/Events/Node/NodeCopiedEvent.php',
'OCP\\Files\\Events\\Node\\NodeCreatedEvent' => $baseDir . '/lib/public/Files/Events/Node/NodeCreatedEvent.php',
'OCP\\Files\\Events\\Node\\NodeDeletedEvent' => $baseDir . '/lib/public/Files/Events/Node/NodeDeletedEvent.php',
'OCP\\Files\\Events\\Node\\NodeRenamedEvent' => $baseDir . '/lib/public/Files/Events/Node/NodeRenamedEvent.php',
'OCP\\Files\\Events\\Node\\NodeTouchedEvent' => $baseDir . '/lib/public/Files/Events/Node/NodeTouchedEvent.php',
'OCP\\Files\\Events\\Node\\NodeWrittenEvent' => $baseDir . '/lib/public/Files/Events/Node/NodeWrittenEvent.php',
'OCP\\Files\\File' => $baseDir . '/lib/public/Files/File.php',
'OCP\\Files\\FileInfo' => $baseDir . '/lib/public/Files/FileInfo.php',
'OCP\\Files\\FileNameTooLongException' => $baseDir . '/lib/public/Files/FileNameTooLongException.php',
Expand Down
15 changes: 15 additions & 0 deletions lib/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,21 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OCP\\Files\\Events\\FolderScannedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/FolderScannedEvent.php',
'OCP\\Files\\Events\\NodeAddedToCache' => __DIR__ . '/../../..' . '/lib/public/Files/Events/NodeAddedToCache.php',
'OCP\\Files\\Events\\NodeRemovedFromCache' => __DIR__ . '/../../..' . '/lib/public/Files/Events/NodeRemovedFromCache.php',
'OCP\\Files\\Events\\Node\\AbstractNodeEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/AbstractNodeEvent.php',
'OCP\\Files\\Events\\Node\\AbstractNodesEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/AbstractNodesEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeCopiedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/BeforeNodeCopiedEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeCreatedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/BeforeNodeCreatedEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeDeletedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/BeforeNodeDeletedEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeReadEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/BeforeNodeReadEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeRenamedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/BeforeNodeRenamedEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeTouchedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/BeforeNodeTouchedEvent.php',
'OCP\\Files\\Events\\Node\\BeforeNodeWrittenEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/BeforeNodeWrittenEvent.php',
'OCP\\Files\\Events\\Node\\NodeCopiedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/NodeCopiedEvent.php',
'OCP\\Files\\Events\\Node\\NodeCreatedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/NodeCreatedEvent.php',
'OCP\\Files\\Events\\Node\\NodeDeletedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/NodeDeletedEvent.php',
'OCP\\Files\\Events\\Node\\NodeRenamedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/NodeRenamedEvent.php',
'OCP\\Files\\Events\\Node\\NodeTouchedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/NodeTouchedEvent.php',
'OCP\\Files\\Events\\Node\\NodeWrittenEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/NodeWrittenEvent.php',
'OCP\\Files\\File' => __DIR__ . '/../../..' . '/lib/public/Files/File.php',
'OCP\\Files\\FileInfo' => __DIR__ . '/../../..' . '/lib/public/Files/FileInfo.php',
'OCP\\Files\\FileNameTooLongException' => __DIR__ . '/../../..' . '/lib/public/Files/FileNameTooLongException.php',
Expand Down
103 changes: 80 additions & 23 deletions lib/private/Files/Node/HookConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,39 @@
use OC\Files\Filesystem;
use OC\Files\View;
use OCP\EventDispatcher\GenericEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Events\Node\BeforeNodeCopiedEvent;
use OCP\Files\Events\Node\BeforeNodeCreatedEvent;
use OCP\Files\Events\Node\BeforeNodeDeletedEvent;
use OCP\Files\Events\Node\BeforeNodeReadEvent;
use OCP\Files\Events\Node\BeforeNodeRenamedEvent;
use OCP\Files\Events\Node\BeforeNodeTouchedEvent;
use OCP\Files\Events\Node\BeforeNodeWrittenEvent;
use OCP\Files\Events\Node\NodeCopiedEvent;
use OCP\Files\Events\Node\NodeCreatedEvent;
use OCP\Files\Events\Node\NodeDeletedEvent;
use OCP\Files\Events\Node\NodeRenamedEvent;
use OCP\Files\Events\Node\NodeTouchedEvent;
use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\Files\FileInfo;
use OCP\Files\IRootFolder;
use OCP\Util;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

class HookConnector {
/**
* @var Root
*/
/** @var IRootFolder */
private $root;

/**
* @var View
*/
/** @var View */
private $view;

/**
* @var FileInfo[]
*/
/** @var FileInfo[] */
private $deleteMetaCache = [];

/** @var EventDispatcherInterface */
private $legacyDispatcher;

/** @var IEventDispatcher */
private $dispatcher;

/**
Expand All @@ -55,9 +68,14 @@ class HookConnector {
* @param Root $root
* @param View $view
*/
public function __construct(Root $root, View $view, EventDispatcherInterface $dispatcher) {
public function __construct(
IRootFolder $root,
View $view,
EventDispatcherInterface $legacyDispatcher,
IEventDispatcher $dispatcher) {
$this->root = $root;
$this->view = $view;
$this->legacyDispatcher = $legacyDispatcher;
$this->dispatcher = $dispatcher;
}

Expand Down Expand Up @@ -86,85 +104,124 @@ public function viewToNode() {
public function write($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'preWrite', [$node]);
$this->dispatcher->dispatch('\OCP\Files::preWrite', new GenericEvent($node));
$this->legacyDispatcher->dispatch('\OCP\Files::preWrite', new GenericEvent($node));

$event = new BeforeNodeWrittenEvent($node);
$this->dispatcher->dispatchTyped($event);
}

public function postWrite($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'postWrite', [$node]);
$this->dispatcher->dispatch('\OCP\Files::postWrite', new GenericEvent($node));
$this->legacyDispatcher->dispatch('\OCP\Files::postWrite', new GenericEvent($node));

$event = new NodeWrittenEvent($node);
$this->dispatcher->dispatchTyped($event);
}

public function create($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'preCreate', [$node]);
$this->dispatcher->dispatch('\OCP\Files::preCreate', new GenericEvent($node));
$this->legacyDispatcher->dispatch('\OCP\Files::preCreate', new GenericEvent($node));

$event = new BeforeNodeCreatedEvent($node);
$this->dispatcher->dispatchTyped($event);
}

public function postCreate($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'postCreate', [$node]);
$this->dispatcher->dispatch('\OCP\Files::postCreate', new GenericEvent($node));
$this->legacyDispatcher->dispatch('\OCP\Files::postCreate', new GenericEvent($node));

$event = new NodeCreatedEvent($node);
$this->dispatcher->dispatchTyped($event);
}

public function delete($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->deleteMetaCache[$node->getPath()] = $node->getFileInfo();
$this->root->emit('\OC\Files', 'preDelete', [$node]);
$this->dispatcher->dispatch('\OCP\Files::preDelete', new GenericEvent($node));
$this->legacyDispatcher->dispatch('\OCP\Files::preDelete', new GenericEvent($node));

$event = new BeforeNodeDeletedEvent($node);
$this->dispatcher->dispatchTyped($event);
}

public function postDelete($arguments) {
$node = $this->getNodeForPath($arguments['path']);
unset($this->deleteMetaCache[$node->getPath()]);
$this->root->emit('\OC\Files', 'postDelete', [$node]);
$this->dispatcher->dispatch('\OCP\Files::postDelete', new GenericEvent($node));
$this->legacyDispatcher->dispatch('\OCP\Files::postDelete', new GenericEvent($node));

$event = new NodeDeletedEvent($node);
$this->dispatcher->dispatchTyped($event);
}

public function touch($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'preTouch', [$node]);
$this->dispatcher->dispatch('\OCP\Files::preTouch', new GenericEvent($node));
$this->legacyDispatcher->dispatch('\OCP\Files::preTouch', new GenericEvent($node));

$event = new BeforeNodeTouchedEvent($node);
$this->dispatcher->dispatchTyped($event);
}

public function postTouch($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'postTouch', [$node]);
$this->dispatcher->dispatch('\OCP\Files::postTouch', new GenericEvent($node));
$this->legacyDispatcher->dispatch('\OCP\Files::postTouch', new GenericEvent($node));

$event = new NodeTouchedEvent($node);
$this->dispatcher->dispatchTyped($event);
}

public function rename($arguments) {
$source = $this->getNodeForPath($arguments['oldpath']);
$target = $this->getNodeForPath($arguments['newpath']);
$this->root->emit('\OC\Files', 'preRename', [$source, $target]);
$this->dispatcher->dispatch('\OCP\Files::preRename', new GenericEvent([$source, $target]));
$this->legacyDispatcher->dispatch('\OCP\Files::preRename', new GenericEvent([$source, $target]));

$event = new BeforeNodeRenamedEvent($source, $target);
$this->dispatcher->dispatchTyped($event);
}

public function postRename($arguments) {
$source = $this->getNodeForPath($arguments['oldpath']);
$target = $this->getNodeForPath($arguments['newpath']);
$this->root->emit('\OC\Files', 'postRename', [$source, $target]);
$this->dispatcher->dispatch('\OCP\Files::postRename', new GenericEvent([$source, $target]));
$this->legacyDispatcher->dispatch('\OCP\Files::postRename', new GenericEvent([$source, $target]));

$event = new NodeRenamedEvent($source, $target);
$this->dispatcher->dispatchTyped($event);
}

public function copy($arguments) {
$source = $this->getNodeForPath($arguments['oldpath']);
$target = $this->getNodeForPath($arguments['newpath']);
$this->root->emit('\OC\Files', 'preCopy', [$source, $target]);
$this->dispatcher->dispatch('\OCP\Files::preCopy', new GenericEvent([$source, $target]));
$this->legacyDispatcher->dispatch('\OCP\Files::preCopy', new GenericEvent([$source, $target]));

$event = new BeforeNodeCopiedEvent($source, $target);
$this->dispatcher->dispatchTyped($event);
}

public function postCopy($arguments) {
$source = $this->getNodeForPath($arguments['oldpath']);
$target = $this->getNodeForPath($arguments['newpath']);
$this->root->emit('\OC\Files', 'postCopy', [$source, $target]);
$this->dispatcher->dispatch('\OCP\Files::postCopy', new GenericEvent([$source, $target]));
$this->legacyDispatcher->dispatch('\OCP\Files::postCopy', new GenericEvent([$source, $target]));

$event = new NodeCopiedEvent($source, $target);
$this->dispatcher->dispatchTyped($event);
}

public function read($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'read', [$node]);
$this->dispatcher->dispatch('\OCP\Files::read', new GenericEvent([$node]));
$this->legacyDispatcher->dispatch('\OCP\Files::read', new GenericEvent([$node]));

$event = new BeforeNodeReadEvent($node);
$this->dispatcher->dispatchTyped($event);
}

private function getNodeForPath($path) {
Expand Down
17 changes: 15 additions & 2 deletions lib/private/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -373,14 +373,21 @@ public function __construct($webRoot, \OC\Config $config) {
$this->getLogger(),
$this->getUserManager()
);
$connector = new HookConnector($root, $view, $c->getEventDispatcher());
$connector->viewToNode();

$previewConnector = new \OC\Preview\WatcherConnector($root, $c->getSystemConfig());
$previewConnector->connectWatcher();

return $root;
});
$this->registerService(HookConnector::class, function (Server $c) {
return new HookConnector(
$c->query(IRootFolder::class),
new View(),
$c->query(\OC\EventDispatcher\SymfonyAdapter::class),
$c->query(IEventDispatcher::class)
);
});

$this->registerDeprecatedAlias('SystemTagObjectMapper', ISystemTagObjectMapper::class);

$this->registerService(IRootFolder::class, function (Server $c) {
Expand Down Expand Up @@ -1359,6 +1366,12 @@ public function __construct($webRoot, \OC\Config $config) {
$this->connectDispatcher();
}

public function boot() {
/** @var HookConnector $hookConnector */
$hookConnector = $this->query(HookConnector::class);
$hookConnector->viewToNode();
}

/**
* @return \OCP\Calendar\IManager
*/
Expand Down
52 changes: 52 additions & 0 deletions lib/public/Files/Events/Node/AbstractNodeEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);
/**
* @copyright Copyright (c) 2020, Roeland Jago Douma <[email protected]>
*
* @author Roeland Jago Douma <[email protected]>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

namespace OCP\Files\Events\Node;

use OCP\EventDispatcher\Event;
use OCP\Files\Node;

/**
* @since 20.0.0
*/
abstract class AbstractNodeEvent extends Event {

/** @var Node */
private $node;

/**
* @since 20.0.0
*/
public function __construct(Node $node) {
$this->node = $node;
}

/**
* @since 20.0.0
*/
public function getNode(): Node {
return $this->node;
}
}
Loading

0 comments on commit b638c6e

Please sign in to comment.