I am using CakePHP 3.2
I am bit new to CakePHP. I am trying to get data from Icases table where the created date is within 10 days, but for some reason it's just returning the first row. Can anyone please let me know what I am doing wrong.
My Controller IcasesController
namespace App\Controller;
use App\Controller\AppController;
/**
* Icases Controller
*
* #property \App\Model\Table\IcasesTable $Icases
*/
class IcasesController extends AppController
{
public function index()
{
$case_count_data = $this->Icases->getCaseCountByAge();
print_r($case_count_data);
}
}
My Table class IcasesTable
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\ORM\TableRegistry;
use DateTime;
class IcasesTable extends Table
{
/**
* Initialize method
*
* #param array $config The configuration for the Table.
* #return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->table('icases');
$this->displayField('name');
$this->primaryKey('id');
$this->belongsTo('Clients', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Documents', [
'foreignKey' => 'icase_id'
]);
$this->belongsToMany('Users', [
'foreignKey' => 'icase_id',
'targetForeignKey' => 'user_id',
'joinTable' => 'icases_users'
]);
}
/**
* Default validation rules.
*
* #param \Cake\Validation\Validator $validator Validator instance.
* #return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->dateTime('date_instruction_received')
->allowEmpty('date_instruction_received');
$validator
->dateTime('date_online_invitation_last_sent')
->allowEmpty('date_online_invitation_last_sent');
$validator
->dateTime('date_approved_for_allocation')
->allowEmpty('date_approved_for_allocation');
$validator
->dateTime('date_consent_received')
->allowEmpty('date_consent_received');
$validator
->dateTime('go_date')
->allowEmpty('go_date');
$validator
->dateTime('date_last_referred_to_client')
->allowEmpty('date_last_referred_to_client');
$validator
->dateTime('date_last_referred_to_qc_report')
->allowEmpty('date_last_referred_to_qc_report');
$validator
->dateTime('date_last_referred_qc')
->allowEmpty('date_last_referred_qc');
$validator
->dateTime('date_last_referred_sub')
->allowEmpty('date_last_referred_sub');
$validator
->dateTime('date_last_state_change')
->allowEmpty('date_last_state_change');
$validator
->dateTime('date_marked_for_archival')
->allowEmpty('date_marked_for_archival');
$validator
->allowEmpty('state');
$validator
->integer('weight')
->allowEmpty('weight');
$validator
->requirePresence('case_reference_i_d', 'create')
->notEmpty('case_reference_i_d')
->add('case_reference_i_d', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);
$validator
->allowEmpty('special_intructions');
$validator
->allowEmpty('international');
$validator
->allowEmpty('name');
$validator
->requirePresence('sms_enabled', 'create')
->notEmpty('sms_enabled');
$validator
->allowEmpty('client_reference');
$validator
->allowEmpty('position_applied_for');
$validator
->integer('age')
->allowEmpty('age');
$validator
->dateTime('date_deleted')
->allowEmpty('date_deleted');
$validator
->dateTime('date_modified')
->allowEmpty('date_modified');
$validator
->dateTime('date_created')
->requirePresence('date_created', 'create')
->notEmpty('date_created');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* #param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* #return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique(['case_reference_i_d']));
$rules->add($rules->existsIn(['client_id'], 'Clients'));
return $rules;
}
/**
* Gets Case count by age 0-10,10-15,15> days
* #return Array ['count0to10'=>00,'count10to15'=>00,'count15'=>00]
*/
public function getCaseCountByAge()
{
$casesTable = TableRegistry::get("Icases");
$query = $casesTable->find("all",['condition'=>['Icases.date_created >' => new DateTime('-10 days')]]);
$data = $query->execute();
return $data->fetch('assoc');
}
}
You should read and practice more according to CakePHP official Doc
public function getCaseCountByAge()
{
$casesTable = TableRegistry::get("Icases");
$query = $casesTable->find("all",['condition'=>['Icases.date_created >' => new DateTime('-10 days')]]);
$data = $query->execute();
return $data->fetch('assoc');
}
It could be very simple
public function getCaseCountByAge()
{
return $this->find("all",['condition'=>['Icases.date_created >' => new DateTime('-10 days')]])->all();
}
Related
I have created a route with Api prefix
$routes->scope('/api', function (RouteBuilder $routes) {
$routes->setExtensions(['json']);
$routes->post(
'/add-categories',
['controller' => 'Miles', 'action' => 'addCategories','prefix'=>'Api']
);
}
I have created a controller file in directory Controller/Api/MilesController.php
I have created a addCategory method like below
public function addCategories()
{
$categoriesTable = $this->fetchTable('Categories');
$categoryEnt = $categoriesTable->newEmptyEntity();
if ($this->request->is('post')) {
$category = $categoriesTable->patchEntity($categoryEnt, $this->request->getData());
if ($categoriesTable->save($category)) {
$responseBody = [
'status' => 201,
'data' => $category
];
}else{
$responseBody = [
'status' => 400,
'data' => $category->getErrors()
];
}
}
$this->set(compact('responseBody'));
$this->viewBuilder()->setOption('serialize', ['responseBody']);
}
In postman if I try to send a post request without any data , then I getting the response like below
{
"responseBody": {
"status": 201,
"data": {
"created": "2022-05-10T20:04:13+09:00",
"modified": "2022-05-10T20:04:13+09:00",
"id": 8
}
}
}
My Model/Table/CategoriesTable.php looks like
<?php
declare(strict_types=1);
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class CategoriesTable extends Table
{
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('categories');
$this->setDisplayField('name');
$this->setPrimaryKey('id');
$this->addBehavior('Timestamp');
$this->hasMany('Products', [
'foreignKey' => 'category_id',
]);
}
public function validationDefault(Validator $validator): Validator
{
$validator
->allowEmptyString('id', null, 'create');
$validator
->scalar('title')
->notEmptyString('title');
$validator
->boolean('status')
->notEmptyString('status');
$validator
->scalar('imageUrl')
->allowEmptyFile('imageUrl');
return $validator;
}
}
Why my notEmptyString validation not working which I have written in CategoriesTable.php file ?
Note : This Api/MilesController.php has no self model. How can I apply CategoriesTable validation here ?
None of your fields are set as being required, ie they are all optional, and when an optional field is missing, no validation rules will be applied.
So for all fields that must be present, use requirePresence(), for example:
$validator
->requirePresence('title', 'create') // required on create, optional on update
->scalar('title')
->notEmptyString('title');
See also
Cookbook > Validation > Creating Validators > Requiring Field Presence
CakePHP 3.8.13 - I have a table model which CAN retrieve the related data from a table and remove it, but when updating/adding an entry, it does not change this data for some reason. So it seems like a correct setup, yet it does not update/add them. In short, it's a "Questions" table and a "Divisions" table, with a relation table called "questions_divisions". In this relation table there is a question_id and a division_id column. If I manually add or remove entries there, it all seems OK. Just when doing patchEntity and save, it does not do it. This is the post data:
'name' => string 'Some name' (length=8)
'questiontype_id' => string '1' (length=1)
'extra' => string '' (length=0)
'answer' => string '' (length=0)
'datafield' => string 'Person.firstname' (length=16)
'divisions' =>
array (size=1)
'_ids' =>
array (size=3)
0 => string '1' (length=1)
1 => string '7' (length=1)
2 => string '5' (length=1)
This is the code that is executed (so the above post data, is $this->request->getData()):
$question = $this->Questions->patchEntity($question, $this->request->getData());
if ($this->Questions->save($question)) {
All this is more or less the same that's happening elsewhere in the application for a different model, which actually DOES add/update the divisions. I also cleared the /tmp/cache just in case, didn't seem to do the trick. I'm at a loss here.
This is the whole table model:
<?php
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* Questions Model
*
* #property \App\Model\Table\QuestiontypesTable|\Cake\ORM\Association\BelongsTo $Questiontypes
* #property \App\Model\Table\ActivitiesTable|\Cake\ORM\Association\BelongsToMany $Activities
* #property \App\Model\Table\BookingformsTable|\Cake\ORM\Association\BelongsToMany $Bookingforms
* #property \App\Model\Table\DivisionsTable|\Cake\ORM\Association\BelongsToMany $Divisions
*
* #method \App\Model\Entity\Question get($primaryKey, $options = [])
* #method \App\Model\Entity\Question newEntity($data = null, array $options = [])
* #method \App\Model\Entity\Question[] newEntities(array $data, array $options = [])
* #method \App\Model\Entity\Question|bool save(\Cake\Datasource\EntityInterface $entity, $options = [])
* #method \App\Model\Entity\Question|bool saveOrFail(\Cake\Datasource\EntityInterface $entity, $options = [])
* #method \App\Model\Entity\Question patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
* #method \App\Model\Entity\Question[] patchEntities($entities, array $data, array $options = [])
* #method \App\Model\Entity\Question findOrCreate($search, callable $callback = null, $options = [])
*/
class QuestionsTable extends Table {
public function beforeFind ($event, $query, $options, $primary) {
$order = $query->clause('order');
if ($order === null || !count($order)) {
$query->order([$this->getAlias() . '.name' => 'ASC']);
}
}
/**
* Initialize method
*
* #param array $config The configuration for the Table.
* #return void
*/
public function initialize(array $config) {
parent::initialize($config);
$this->setTable('questions');
$this->setDisplayField('name');
$this->setPrimaryKey('id');
$this->addBehavior('Search.Search');
$this->addBehavior('Page');
$this->hasMany('Questions_divisions', [
'foreignKey' => 'question_id'
]);
$this->belongsTo('Questiontypes', [
'foreignKey' => 'questiontype_id',
'joinType' => 'INNER'
]);
$this->belongsToMany('Activities', [
'foreignKey' => 'question_id',
'targetForeignKey' => 'activity_id',
'joinTable' => 'activities_questions'
]);
$this->belongsToMany('Bookingforms', [
'foreignKey' => 'questions_id',
'targetForeignKey' => 'bookingforms_id',
'joinTable' => 'questions_bookingforms'
]);
$this->belongsToMany('Divisions', [
'foreignKey' => 'question_id',
'targetForeignKey' => 'division_id',
'joinTable' => 'questions_divisions'
]);
//Setup searchfield
$this->behaviors()->Page->searchSetup($this->behaviors()->Search->searchManager(), $this->searchForm());
}
/**
* Default validation rules.
*
* #param \Cake\Validation\Validator $validator Validator instance.
* #return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator) {
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->scalar('name')
->maxLength('name', 500)
->requirePresence('name', 'create')
->notEmpty('name');
$validator
->scalar('extra')
->maxLength('extra', 500)
->allowEmpty('extra');
$validator
->scalar('answer')
->maxLength('answer', 1500)
->allowEmpty('answer');
$validator
->scalar('datafield')
->maxLength('datafield', 500)
->requirePresence('datafield', 'create')
->notEmpty('datafield');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* #param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* #return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules) {
$rules->add($rules->existsIn(['questiontype_id'], 'Questiontypes'));
return $rules;
}
/**
* Returns an array which describes the search form
*
* #return Array with search setup
*/
public function searchForm() {
//Set up search form
$search_data = [['id' => 'name', 'label' => 'Naam', 'type' => 'textfield', 'fields' => ['name']],
['id' => 'Questiontypes_id', 'label' => 'Vraagtype', 'type' => 'multiselect', 'fields' => ['Questiontypes.id'], 'options' => $this->Questiontypes->find('list')],
['id' => 'datafield', 'label' => 'Dataveld', 'type' => 'textfield', 'fields' => ['datafield']]
];
return $search_data;
}
}
Seems like adding this column in the $_accessible array (inside the Model/Entity) does the trick... That's why it could retrieve the data, but not edit it - hence "accessible" maybe? Not sure if that's the correct name for it but hey..
protected $_accessible = [
'name' => true,
'extra' => true,
'answer' => true,
'datafield' => true,
'questiontype_id' => true,
'questiontype' => true,
'activities' => true,
'bookingforms' => true,
'divisions' => true // this did the trick!
];
I'm using Cakephp 3.2 and proffer plugin to upload images.
By default the path of the image is as follows
/media/files/<tablename>/<primary_key>/<filename>
Each time a new row is inserted into same table a new folder is created by its primary key.
I want to upload all images of a table to the same directory. means path like
/media/files/<tablename>/<filename>
I'm using event listener as per given in proffer documentation.
This is my SellersTable.php
<?php
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\Event\Event;
class SellersTable extends Table
{
/**
* Initialize method
*
* #param array $config The configuration for the Table.
* #return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$listener = new App\Event\UploadFileNameListener(); // line 23
$this->eventManager()->on($listener);
$this->table('sellers');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->addBehavior('Proffer.Proffer', [
'profile_picture' => [
'root' => Configure::read('ArgoSystems.media.upload') . DS . 'files',
'dir' => 'dir'
]
]);
}
/**
* Default validation rules.
*
* #param \Cake\Validation\Validator $validator Validator instance.
* #return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->requirePresence('first_name', 'create')
->notEmpty('first_name');
$validator
->requirePresence('last_name', 'create')
->notEmpty('last_name');
$validator
->email('email')
->requirePresence('email', 'create')
->notEmpty('email')
->add('email', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);
$validator->provider('proffer', 'Proffer\Model\Validation\ProfferRules');
$validator
->add('profile_picture', 'proffer', [
'rule' => ['dimensions', [
'min' => ['w' => 100, 'h' => 500],
'max' => ['w' => 100, 'h' => 500],
]],
'message' => 'Image must be of 100 x 500 resolution',
'provider' => 'proffer'
])
->requirePresence('profile_picture', 'create')
->allowEmpty('profile_picture','update');
$validator
->requirePresence('password', 'create')
->notEmpty('password');
return $validator;
}
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique(['email']));
return $rules;
}
}
and created UploadFileNameListener.php in src/Event/
<?php
namespace App\Event;
use Cake\Event\Event;
use Cake\Event\EventListenerInterface;
use Cake\Utility\Inflector;
use Proffer\Lib\ProfferPath;
class UploadFileNameListener implements EventListenerInterface
{
public function implementedEvents()
{
return [
'Proffer.afterPath' => 'change',
];
}
/**
* Rename a file and change it's upload folder before it's processed
*
* #param Event $event The event class with a subject of the entity
* #param ProfferPath $path
* #return ProfferPath $path
*/
public function change(Event $event, ProfferPath $path)
{
// Detect and select the right file extension
switch ($event->subject()->get('image')['type']) {
default:
case "image/jpeg":
$ext = '.jpg';
break;
case "image/png":
$ext = '.png';
break;
case "image/gif":
$ext = '.gif';
break;
}
// Create a new filename using the id and the name of the entity
$newFilename = $event->subject()->get('id') . '_' . Inflector::slug($event->subject()->get('name')) . $ext;
// set seed
$path->setSeed('profile_picture');
// Change the filename in both the path to be saved, and in the entity data for saving to the db
$path->setFilename($newFilename);
$event->subject('image')['name'] = $newFilename;
// Must return the modified path instance, so that things are saved in the right place
return $path;
}
}
But this is giving Fatal error as
Error: Uncaught Error: Class 'App\Model\Table\App\Event\UploadFileNameListener' not found in
/var/www/html/projects/admin/src/Model/Table/SellersTable.php:23
From the error message, it's clear that it's trying to load the class with a namespace relative to the namespace of your current class. Try
$listener = new \App\Event\UploadFileNameListener();
I've been following the CakePHP 3.0 tutorials (Bookmarker & Blog) regarding the Login/Authentication sections and applying it to my own code, but I can't seem to get it working properly.
I'm able to see all indexes without even being logged in. Logging into the system does not work; the login page just refreshes.
EDIT: Okay, seems like my test users were duds, I made a new user and it can login. However, I still have the issue of non-users being able to see indexes of tables (they can't create any variables in any of the tables apart from User, which has been allowed specifically).
EDIT2: I fixed it by removing the beforeFilter function in AppController.
User Controller:
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
class UsersController extends AppController
{
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow(['add', 'logout']);
}
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Incorrect username or password, please try again.'));
}
}
public function logout()
{
$this->Flash->success('You are now logged out.');
return $this->redirect($this->Auth->logout());
}
public function index()
{
$this->set('users', $this->Users->find('all'));
}
public function view($id)
{
$user = $this->Users->get($id);
$this->set(compact('user'));
}
}
App Controller:
<?php
namespace App\Controller;
use Cake\Controller\Controller;
use Cake\Event\Event;
class AppController extends Controller
{
public function initialize()
{
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'loginRedirect' => [
'controller' => 'Users',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Pages',
'action' => 'display',
'home'
]
]);
}
}
User Table:
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class UsersTable extends Table
{
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->requirePresence('username', 'create')
->notEmpty('username', 'A username is required');
$validator
->requirePresence('password', 'create')
->notEmpty('password', 'A password is required');
$validator
->email('email')
->requirePresence('email', 'create')
->notEmpty('email', 'An email is required');
$validator
->requirePresence('role', 'create')
->notEmpty('role', 'inList', [
'rule' => ['inList', ['admin', 'artist', 'engineer']],
'message' => 'Please enter a valid role'
]);
return $validator;
}
}
I managed to fix it by removing the beforeFilter function in AppController.
public function beforeSave(Event $event)
{
$entity = $event->data['entity'];
// Make a password for digest auth.
$entity->digest_hash = DigestAuthenticate::password(
$entity->username,
$entity->password,
env('SERVER_NAME')
);
return true;
}
I have a problem with my cakephp3 app. I try to import some subscribers from a CSV file.
I use a Behavior to import my file (https://github.com/ProLoser/CakePHP-CSV). I haven't manage to load the plugin, so I have put the Behavior file on my project under src/Model/Behavior.
I have added the behavior to my SubscribersTable.
I have created a new view (import/export) and I have added this method to my SubscribersController :
public function importExport()
{
if ($this->request->is('post'))
{
$data = $this->request->data;
if(!empty($data['import_file']['name']))
{
$file = $data['import_file'];
if ((isset($file['tmp_name']) &&($file['error'] == UPLOAD_ERR_OK)))
{
$subscribersData = $this->Subscribers->importCsv($file['tmp_name']);
$entities = $this->Subscribers->newEntities($subscribersData);
$table = $this->Subscribers;
$table->connection()->transactional(function () use ($table, $entities) {
foreach ($entities as $entity) {
$table->save($entity, ['atomic' => false]);
}
});
}
}
}
}
The data I get seems to be good, as the entities created, but, when I call $table-save(), I have this error :
Table "App\Model\Table\SubscribersTable" is not associated with "request"
I have read some other questions on stackoverflow, but I don't understand why I have this error. I am new to cakephp so I don't understand everything...
If can someone help me...
Thanks !!
EDIT : It seems during the debug, the behavior is strange. Maybe this error has nothing to see with my real problem.
Here is the debug timeline :
$table->save() call:
if ($options['atomic']) {
$success = $connection->transactional(function () use ($entity, $options) {
return $this->_processSave($entity, $options);
});
} else {
===> $success = $this->_processSave($entity, $options);
}
...
$this->_processSave call :
$data = $entity->extract($this->schema()->columns(), true);
and during the extract, no column is retrieved because
public function extract(array $properties, $onlyDirty = false)
{
$result = [];
foreach ($properties as $property) {
if (!$onlyDirty || $this->dirty($property)) {
$result[$property] = $this->get($property);
}
}
return $result;
}
$onlyDirty = true and $this->dirty($property)) return false.
So, when this function is called
$success = $this->_insert($entity, $data);
as the data is null, nothing is saved.
I don't really understant the concept of dirty. In the doc, it seems it is usefull when working with BelongToMany, but this element has no link with other tables, so if someone can clarify this concept ?
SubscribersTable :
<?php
namespace App\Model\Table;
use App\Model\Entity\Subscriber;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* Subscribers Model
*
*/
class SubscribersTable extends Table
{
/**
* Initialize method
*
* #param array $config The configuration for the Table.
* #return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->table('subscribers');
$this->displayField('email');
$this->primaryKey('email');
$options = array(
// Refer to php.net fgetcsv for more information
'length' => 0,
'delimiter' => ',',
'enclosure' => '"',
'escape' => '\\',
// Generates a Model.field headings row from the csv file
'headers' => true,
// If true, String $content is the data, not a path to the file
'text' => false,
);
$this->addBehavior('Csv', $options);
}
/**
* Default validation rules.
*
* #param \Cake\Validation\Validator $validator Validator instance.
* #return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->add('email', 'valid', ['rule' => 'email'])
->allowEmpty('email', 'create');
$validator
->allowEmpty('contact');
$validator
->allowEmpty('company');
$validator
->allowEmpty('postal_code');
$validator
->add('vip', 'valid', ['rule' => 'boolean'])
->allowEmpty('vip');
$validator
->add('indoor', 'valid', ['rule' => 'boolean'])
->allowEmpty('indoor');
$validator
->add('live', 'valid', ['rule' => 'boolean'])
->allowEmpty('live');
$validator
->add('prod', 'valid', ['rule' => 'boolean'])
->allowEmpty('prod');
$validator
->allowEmpty('localisation');
$validator
->allowEmpty('family');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* #param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* #return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique(['email']));
return $rules;
}
}
This error likely comes from inside your SubscribersTable.php.
If you have $this->request ... in that file, it will throw that error because it's attempting to find request as an associated model, since it's not a valid method to call from a model.
Or, if it's in your controller, you likely have $this->Subscribers->request...
It could also be from inside another Model if you refer to it like this: $this->Subscribers->request ...
Ok.
As I thought, the problem wasn't this error (probably due to the use of the debugger), but it was the structure of my input file.
The input file must be formatted as indicated in this document :
http://book.cakephp.org/3.0/en/orm/saving-data.html#converting-multiple-records
The problem has been resolved !
Thanks again for you help !