diff --git a/includes/class-DailyEvents.php b/includes/class-DailyEvents.php
index 80e0a4d..eb6cd1e 100644
--- a/includes/class-DailyEvents.php
+++ b/includes/class-DailyEvents.php
@@ -1,76 +1,95 @@
 <?php
-# Linux Day 2016 - List events daily
-# Copyright (C) 2016, 2017 Valerio Bozzolan, Ludovico Pavesi, Linux Day Torino
+# from Linux Day 2016 - now Suckless Conference
+# Copyright (C) 2016, 2017, 2018, 2019, 2020 Valerio Bozzolan, Ludovico Pavesi, Linux Day Torino
 #
 # 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/>.
 
 /**
  * Handle a table of daily events
  */
 class DailyEvents {
 
 	/**
-	 * Get daily events from a conference and a chapter
+	 * Get the daily Event(s) from a Conference and a Chapter ID
+	 *
+	 * As default the Event(s) are joined with Track, Chapter and Room.
 	 *
 	 * @param $conference object Conference
 	 * @param $chapter object Chapter
-	 * @param $fields array Fields to be selected
+	 * @param $fields array Fields to be selected from the full Event object
+	 * @param $additional_conditions callable Callback that can be used to apply additional Query conditions. First argument: Query object.
 	 * @return array
 	 */
-	public static function fromConferenceChapter( $conference, $chapter, $fields = [] ) {
+	public static function fromConferenceChapter( $conference, $chapter, $fields = [], $additional_conditions = null ) {
 
 		$conference_ID = $conference->getConferenceID();
 		$chapter_ID = $chapter->getChapterID();
 
-		$events = FullEvent::factoryByConferenceChapter( $conference_ID, $chapter_ID )
+		// prepare the query
+		$events_query = ( new QueryEvent() )
+			->joinTrack()
+			->joinChapter()
+			->joinRoom()
+			->whereConferenceID( $conference_ID )
+			->whereChapterID( $chapter_ID )
 			->select( $fields )
 			->orderBy( Event::START )
-			->orderBy( Track::ORDER )
-			->queryResults();
+			->orderBy( Track::ORDER );
+
+		// check if we should apply additional conditions
+		if( $additional_conditions ) {
+			$additional_conditions( $events_query );
+		}
 
+		// query all the Events in an array
+		$events = $events_query->queryResults();
+
+		// index all the Events
 		$incremental_hour = 0;
 		$last_hour = -1;
 		$last_event_ID = -1;
 		foreach( $events as $i => $event ) {
-			// Remember that it's a JOIN with duplicates
+
+			// Remember that it's a JOIN with duplicates (TODO: untrue now I think)
 			if( $last_event_ID === $event->getEventID() ) {
 				unset( $events[ $i ] );
 				continue;
 			}
 
 			// 'G': date() 0-24 hour format without leading zeros
 			$hour = (int) $event->getEventStart( 'G' );
 
 			// Next hour
 			if( $hour !== $last_hour ) {
 				if( $incremental_hour === 0 ) {
 					$incremental_hour = 1;
 				} else {
 					// `$hour - $last_hour` is often only 1
 					// Set to ++ to skip empty spaces
 					$incremental_hour += $hour - $last_hour;
 				}
 			}
 
 			// Fill `->hour`
 			$event->hour = $incremental_hour;
 
-			$last_event_ID = $event->event_ID;
+			// (TODO: remove, should work)
+			$last_event_ID = $event->getEventID();
 
 			$last_hour = $hour;
 		}
 
 		return $events;
 	}
 }
diff --git a/includes/class-QueryChapter.php b/includes/class-QueryChapter.php
new file mode 100644
index 0000000..928e4aa
--- /dev/null
+++ b/includes/class-QueryChapter.php
@@ -0,0 +1,82 @@
+<?php
+# Linux Day Torino website - classes
+# Copyright (C) 2020 Valerio Bozzolan
+#
+# 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/>.
+
+/**
+ * Methods related to a QueryChapter class
+ */
+trait QueryChapterTrait {
+
+	/**
+	 * Where the Chapter is...
+	 *
+	 * @param  object $event Chapter
+	 * @return self
+	 */
+	public function whereChapter( $event ) {
+		return $this->whereChapterID( $event->getChapterID() );
+	}
+
+	/**
+	 * Where the Chapter ID is...
+	 *
+	 * @param  int  $id Chapter ID
+	 * @return self
+	 */
+	public function whereChapterID( $id ) {
+		return $this->whereInt( $this->CHAPTER_ID, $id );
+	}
+
+	/**
+	 * Join a generic table with the Chapter table
+	 *
+	 * @param string $type Join type
+	 * @return self
+	 */
+	public function joinChapter( $type = 'INNER' ) {
+
+		// build the:
+		//  INNER JOIN chapter ON (chapter.chapter_ID = chapter_ID)
+		return $this->joinOn( $type, Chapter::T, Chapter::ID_, $this->CHAPTER_ID );
+	}
+
+}
+
+/**
+ * Utility used to Query a Chapter.
+ */
+class QueryChapter {
+
+	use QueryChapterTrait;
+
+	/**
+	 * Full name of the column of the Chapter ID
+	 */
+	protected $CHAPTER_ID = 'chapter_ID';
+
+	/**
+	 * Constructor
+	 */
+	public function __construct() {
+
+		parent::__construct();
+
+		$this->from( Chapter::T );
+
+		$this->defaultClass( Chapter::class );
+	}
+
+}
diff --git a/includes/class-QueryEvent.php b/includes/class-QueryEvent.php
index 6e4e4cb..61f2e96 100644
--- a/includes/class-QueryEvent.php
+++ b/includes/class-QueryEvent.php
@@ -1,200 +1,196 @@
 <?php
 # Linux Day Torino website - classes
-# Copyright (C) 2018, 2019 Valerio Bozzolan, Linux Day Torino
+# Copyright (C) 2018, 2019, 2020 Valerio Bozzolan, Linux Day Torino
 #
 # 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/>.
 
 // load dependent traits
 class_exists( QueryConference::class, true );
+class_exists( QueryChapter   ::class, true );
+class_exists( QueryTrack     ::class, true );
+class_exists( QueryRoom      ::class, true );
 
 /**
  * Methods for a QueryEvent class
  */
 trait QueryEventTrait {
 
 	use QueryConferenceTrait;
 
 	/**
 	 * Where the Event is...
 	 *
 	 * @param  object $event Event
 	 * @return self
 	 */
 	public function whereEvent( $event ) {
 		return $this->whereEventID( $event->getEventID() );
 	}
 
 	/**
 	 * Where the Event ID is...
 	 *
 	 * @param  int  $id Event ID
 	 * @return self
 	 */
 	public function whereEventID( $id ) {
 		return $this->whereInt( $this->EVENT_ID, $id );
 	}
 
 	/**
 	 * Where the Event UID is this one
 	 *
 	 * @param  string $uid Event UID
 	 * @return self
 	 */
 	public function whereEventUID( $uid ) {
 		return $this->whereStr( Event::UID, $uid );
 	}
 
 	/**
 	 * Where the Event is editable by me
 	 */
 	public function whereEventIsEditable() {
 		throw new Exception( "to be implemented" );
 	}
 }
 
 /**
  * Class able to query a FullEvent.
  */
 class QueryEvent extends Query {
 
 	use QueryEventTrait;
+	use QueryChapterTrait;
+	use QueryTrackTrait;
+	use QueryRoomTrait;
 
 	/**
 	 * Univoque Event ID column name
 	 *
 	 * @var
 	 */
 	protected $EVENT_ID = 'event.event_ID';
 
 	/**
 	 * Univoque Chapter ID column name
 	 *
 	 * @var
 	 */
 	protected $CHAPTER_ID = 'event.chapter_ID';
 
 	/*
 	 * Univoque Conference ID column name
 	 *
 	 * Used from ConferenceTrait#joinConference()
 	 *
 	 * @var
 	 */
 	protected $CONFERENCE_ID = 'event.conference_ID';
 
 	/**
 	 * Univoque Track ID column name
 	 *
 	 * @var
 	 */
 	protected $TRACK_ID = 'event.track_ID';
 
 	/**
 	 * Univoque Room ID column name
 	 *
 	 * @var
 	 */
 	protected $ROOM_ID = 'event.room_ID';
 
 	/**
 	 * Constructor
 	 */
 	public function __construct() {
 		parent::__construct();
 		$this->from( Event::T );
 		$this->defaultClass( FullEvent::class );
 	}
 
 	/**
 	 * Limit to a certain User
 	 *
 	 * @deprecated
 	 *
 	 * @param $user User
 	 * @return self
 	 */
 	public function whereUser( $user ) {
 		return $this->joinEventUser()
 		            ->whereInt( EventUser::USER_, $user->getUserID() );
 	}
 
-	/**
-	 * Join a table with the Chapter table
-	 *
-	 * @param string $type Join type
-	 * @return self
-	 */
-	public function joinChapter( $type = 'INNER' ) {
-		return $this->joinOn( $type, 'chapter', 'chapter.chapter_ID' , $this->CHAPTER_ID );
-	}
-
 	/**
 	 * Join a table with the Track table
 	 *
 	 * @return self
 	 */
 	public function joinTrack() {
 		return $this->joinOn( 'INNER', Track::T, Track::ID_, $this->TRACK_ID );
 	}
 
 	/**
 	 * Join a table with the Room table
 	 *
 	 * @return self
 	 */
 	public function joinRoom() {
 		return $this->joinOn( 'INNER', Room::T, Room::ID_, $this->ROOM_ID );
 	}
 
 	/**
 	 * Join Events to User IDs
 	 *
 	 * You can call it multiple time safely.
 	 *
 	 * @return self
 	 */
 	public function joinEventUser() {
 		if( empty( $this->joinedEventUser ) ) {
 			$this->from(   EventUser::T                  );
 			$this->equals( EventUser::EVENT_, Event::ID_ );
 			$this->joinedEventUser = true;
 		}
 		return $this;
 	}
 
 	/**
 	 * Join Events and their Track, Chapter and Room (can be NULL).
 	 *
 	 * You can call it multiple time safely.
 	 *
 	 * @return self
 	 */
 	public function joinTrackChapterRoom() {
 		if( empty( $this->joinedTrackChapterRoom ) ) {
 
 			$this->from(   Room::T )
 			     ->equals( Room::ID_,    Event::ROOM_ );
 
 			$this->from(   Track::T )
 			     ->equals( Track::ID_,   Event::TRACK_ );
 
 			$this->from(   Chapter::T )
 			     ->equals( Chapter::ID_, Event::CHAPTER_ );
 
 			$this->joinedTrackChapterRoom = true;
 		}
 		return $this;
 	}
 
 }
diff --git a/includes/class-QueryRoom.php b/includes/class-QueryRoom.php
new file mode 100644
index 0000000..86f2763
--- /dev/null
+++ b/includes/class-QueryRoom.php
@@ -0,0 +1,82 @@
+<?php
+# Linux Day Torino website - classes
+# Copyright (C) 2020 Valerio Bozzolan
+#
+# 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/>.
+
+/**
+ * Methods related to a QueryRoom class
+ */
+trait QueryRoomTrait {
+
+	/**
+	 * Where the Room is...
+	 *
+	 * @param  object $event Room
+	 * @return self
+	 */
+	public function whereRoom( $event ) {
+		return $this->whereRoomID( $event->getRoomID() );
+	}
+
+	/**
+	 * Where the Room ID is...
+	 *
+	 * @param  int  $id Room ID
+	 * @return self
+	 */
+	public function whereRoomID( $id ) {
+		return $this->whereInt( $this->ROOM_ID, $id );
+	}
+
+	/**
+	 * Join a generic table with the Room table
+	 *
+	 * @param string $type Join type
+	 * @return self
+	 */
+	public function joinRoom( $type = 'INNER' ) {
+
+		// build the:
+		//  INNER JOIN room ON (room.room_ID = room_ID)
+		return $this->joinOn( $type, Room::T, Room::ID_, $this->ROOM_ID );
+	}
+
+}
+
+/**
+ * Utility used to Query a Room.
+ */
+class QueryRoom {
+
+	use QueryRoomTrait;
+
+	/**
+	 * Full name of the column of the Room ID
+	 */
+	protected $ROOM_ID = 'room_ID';
+
+	/**
+	 * Constructor
+	 */
+	public function __construct() {
+
+		parent::__construct();
+
+		$this->from( Room::T );
+
+		$this->defaultClass( Room::class );
+	}
+
+}
diff --git a/includes/class-QueryTrack.php b/includes/class-QueryTrack.php
new file mode 100644
index 0000000..5686df3
--- /dev/null
+++ b/includes/class-QueryTrack.php
@@ -0,0 +1,82 @@
+<?php
+# Linux Day Torino website - classes
+# Copyright (C) 2020 Valerio Bozzolan
+#
+# 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/>.
+
+/**
+ * Methods related to a QueryTrack class
+ */
+trait QueryTrackTrait {
+
+	/**
+	 * Where the Track is...
+	 *
+	 * @param  object $event Track
+	 * @return self
+	 */
+	public function whereTrack( $event ) {
+		return $this->whereTrackID( $event->getTrackID() );
+	}
+
+	/**
+	 * Where the Track ID is...
+	 *
+	 * @param  int  $id Track ID
+	 * @return self
+	 */
+	public function whereTrackID( $id ) {
+		return $this->whereInt( $this->TRACK_ID, $id );
+	}
+
+	/**
+	 * Join a generic table with the Track table
+	 *
+	 * @param string $type Join type
+	 * @return self
+	 */
+	public function joinTrack( $type = 'INNER' ) {
+
+		// build the:
+		//  INNER JOIN track ON (track.track_ID = track_ID)
+		return $this->joinOn( $type, Track::T, Track::ID_, $this->TRACK_ID );
+	}
+
+}
+
+/**
+ * Utility used to Query a Track.
+ */
+class QueryTrack {
+
+	use QueryTrackTrait;
+
+	/**
+	 * Full name of the column of the Track ID
+	 */
+	protected $TRACK_ID = 'track_ID';
+
+	/**
+	 * Constructor
+	 */
+	public function __construct() {
+
+		parent::__construct();
+
+		$this->from( Track::T );
+
+		$this->defaultClass( Track::class );
+	}
+
+}