CakePHP 3.x Query many Table objects with Pagination

Context:
I’m working with CakePHP 3.x and I’m trying to build an ORM query with pagination. I have the tables Users, Topics and Areas. User can have many topics but just one area. This is the db model:

CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
);
CREATE TABLE topics (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
name VARCHAR(255),
description TEXT,
FOREIGN KEY user_key (user_id) REFERENCES users(id)
);
CREATE TABLE areas (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
UNIQUE KEY (title)
);
CREATE TABLE users_areas (
user_id INT NOT NULL,
area_id INT NOT NULL,
PRIMARY KEY (user_id, area_id),
FOREIGN KEY area_key(area_id) REFERENCES areas(id),
FOREIGN KEY user_key(user_id) REFERENCES users(id)
);

What I need
I need to get all the Topics filtered by an area given.
I’m trying the next:

//1. get the area from the url (OK)
$area = $this->request->getQuery('area');

//2. Get the area from db to get the id
$myarea = $this->Areas->find()->where(['title' => $area])->first();

//3. Get all the users related to the area given
$users = $this->Users->find()->matching('Areas', function ($q){
            return $q->where(['Areas.id' => $myarea->id]);
          });

//4. Get the Topics and Paginate
$topics = $this->paginate($this->Topics->find('all')->innerJoinWith('Users', function ($q){
          return $q->where(['User.id' => $myarea->id]);
        }));

//5. Set the topics (OK)
$this->set(compact('topics'));
$this->set('_serialize', ['topics']);

I got tons of errors and I’m not sure how to build the query properly.

Given your table structure I’d say you can’t filter topics by an area unless you are filtering by users. Topics and areas have no direct relationship.

In closures you don’t have access to external variables unless you declare them. Like this

//2. Get the area from db to get the id
$myarea = $this->Areas->find()->where(['title' => $area])->first();

//3. Get all the users related to the area given
$users = $this->Users->find()->matching('Areas', function ($q) use ($myarea) {
    return $q->where(['Areas.id' => $myarea->id]);
});

The missing use () is why you get undefined var error