Serialization of Closure is not allowed
Closed this issue · 14 comments
After installing the extension succesfully, I get the following error when trying to get an enityt called Match, which has a Venue
Exception
Serialization of 'Closure' is not allowed
SYSTEMPATH\Cache\Handlers\FileHandler.php at line 134
127
128 $contents = [
129 'time' => time(),
130 'ttl' => $ttl,
131 'data' => $value,
132 ];
133
134 if ($this->writeFile($this->path . $key, serialize($contents)))
135 {
136 chmod($this->path . $key, 0640);
137
138 return true;
139 }
140
141 return false;
This is my controller code:
public function __construct()
{
$this->restrictToGroups('admins', base_url('login') );
$this->matchModel = model('Models\MatchModel');
}
public function index()
{
$this->data['matches'] = $this->matchModel->includeRelated(VenueModel::class)->findAll();
echo view('admin/match', $this->data);
}
This is the MatchModel:
<?php namespace App\Models;
use OrmExtension\Extensions\Model;
class MatchModel extends Model
{
public $hasOne = [
VenueModel::class,
];
}
And this is the VenueModel:
<?php namespace App\Models;
use OrmExtension\Extensions\Model;
class VenueModel extends Model
{
public $hasMany = [
MatchModel::class
];
}
Can you provide a full stack trace?
Can you try this
$matchModel = new MatchModel();
$this->data['matches'] = $matchModel->includeRelated(VenueModel::class)->find();
I tried it like you suggested, this is the backtrace:
SYSTEMPATH\Cache\Handlers\FileHandler.php : 134 — serialize()
VENDORPATH\4spacesdk\ci4ormextension\DataMapper\ModelDefinitionCache.php : 128 — CodeIgniter\Cache\Handlers\FileHandler->save ( arguments )
121
122
123
124
125 private static function setData($name, $data, $ttl = YEAR) {
126 $instance = ModelDefinitionCache::getInstance();
127 if(isset($instance->cache))
128 $instance->cache->save($name, $data, $ttl);
129 }
130
131 private $memcache = [];
132 private static function getData($name) {
133 try {
134 $instance = ModelDefinitionCache::getInstance();
135 if(!isset($instance->memcache[$name])) {
VENDORPATH\4spacesdk\ci4ormextension\DataMapper\ModelDefinitionCache.php : 91 — OrmExtension\DataMapper\ModelDefinitionCache::setData ( arguments )
84 throw $e;
85 }
86 }
87 return $fieldData;
88 }
89
90 public static function setRelations($entity, $relations) {
91 static::setData($entity.'_relations', $relations);
92 }
93
94 /**
95 * @param $entity
96 * @return RelationDef[]
97 * @throws \Exception
98 */
VENDORPATH\4spacesdk\ci4ormextension\DataMapper\ModelDefinitionCache.php : 116 — OrmExtension\DataMapper\ModelDefinitionCache::setRelations ( arguments )
109 }
110 }
111 $relations = [];
112 foreach($model->hasOne as $name => $hasOne)
113 $relations[] = new RelationDef($model, $name, $hasOne, RelationDef::HasOne);
114 foreach($model->hasMany as $name => $hasMany)
115 $relations[] = new RelationDef($model, $name, $hasMany, RelationDef::HasMany);
116 ModelDefinitionCache::setRelations($entity, $relations);
117 }
118 return $relations;
119 }
120
121
122
123
VENDORPATH\4spacesdk\ci4ormextension\DataMapper\QueryBuilder.php : 428 — OrmExtension\DataMapper\ModelDefinitionCache::getRelations ( arguments )
421 }
422
423 /**
424 * @return RelationDef[]
425 */
426 public function getRelations() {
427 $entityName = $this->_getModel()->getEntityName();
428 $relations = ModelDefinitionCache::getRelations($entityName);
429 return $relations;
430 }
431
432 // </editor-fold>
433
434 }
435
VENDORPATH\4spacesdk\ci4ormextension\DataMapper\QueryBuilder.php : 412 — OrmExtension\Extensions\Model->getRelations ()
405 $relation = $relations[0];
406 $last = $relation->getRelationClass();
407 $result[] = $relation;
408 }
409 return $result;
410 }
411
412 foreach($this->getRelations() as $relation) {
413 if($useSimpleName) {
414 if($relation->getSimpleName() == $name) return [$relation];
415 } else {
416 if($relation->getName() == $name) return [$relation];
417 }
418 }
419
VENDORPATH\4spacesdk\ci4ormextension\DataMapper\QueryBuilder.php : 19 — OrmExtension\Extensions\Model->getRelation ( arguments )
12 /**
13 * @param string|array $relationName
14 * @param null $fields
15 * @return Model
16 */
17 public function includeRelated($relationName, $fields = null): Model {
18 $parent = $this->_getModel();
19 $relations = $this->getRelation($relationName);
20
21 // Handle deep relations
22 $last = $this;
23 $table = null;
24 $prefix = ''; $relationPrefix = '';
25 foreach($relations as $relation) {
26 $table = $last->addRelatedTable($relation, $prefix, $table, $fields);
APPPATH\Controllers\Admin\Match.php : 22 — OrmExtension\Extensions\Model->includeRelated ( arguments )
15
16 public function index()
17 {
18
19
20
21 $matchModel = new MatchModel();
22 $this->data['matches'] = $matchModel->includeRelated(VenueModel::class)->find();
23
24 echo view('admin/match', $this->data);
25 }
26
27
28 }
29
SYSTEMPATH\CodeIgniter.php : 914 — App\Controllers\Admin\Match->index ()
907
908 if (method_exists($class, '_remap'))
909 {
910 $output = $class->_remap($this->method, ...$params);
911 }
912 else
913 {
914 $output = $class->{$this->method}(...$params);
915 }
916
917 $this->benchmark->stop('controller');
918
919 return $output;
920 }
921
SYSTEMPATH\CodeIgniter.php : 400 — CodeIgniter\CodeIgniter->runController ( arguments )
393 if (! is_callable($this->controller))
394 {
395 $controller = $this->createController();
396
397 // Is there a "post_controller_constructor" event?
398 Events::trigger('post_controller_constructor');
399
400 $returned = $this->runController($controller);
401 }
402 else
403 {
404 $this->benchmark->stop('controller_constructor');
405 $this->benchmark->stop('controller');
406 }
407
SYSTEMPATH\CodeIgniter.php : 308 — CodeIgniter\CodeIgniter->handleRequest ( arguments )
301
302 $this->response->pretend($this->useSafeOutput)->send();
303 $this->callExit(EXIT_SUCCESS);
304 }
305
306 try
307 {
308 return $this->handleRequest($routes, $cacheConfig, $returnResponse);
309 }
310 catch (RedirectException $e)
311 {
312 $logger = Services::logger();
313 $logger->info('REDIRECTED ROUTE at ' . $e->getMessage());
314
315 // If the route is a 'redirect' route, it throws
FCPATH\index.php : 45 — CodeIgniter\CodeIgniter->run ()
38 /*
39 *---------------------------------------------------------------
40 * LAUNCH THE APPLICATION
41 *---------------------------------------------------------------
42 * Now that everything is setup, it's time to actually fire
43 * up the engines and make this app do its thang.
44 */
45 $app->run();
46
It's complaining about a Closure in the relation data. Do you have a Closure in one of your hasOne or hasMany definitions?
I'm not sure if I understand what a closure is, but I don;t think so. The definitions in the models look like this:
MatchModel
<?php namespace App\Models;
use OrmExtension\Extensions\Model;
class MatchModel extends Model
{
public $hasOne = [
VenueModel::class,
];
}
VenueModel:
<?php namespace App\Models;
use OrmExtension\Extensions\Model;
class VenueModel extends Model
{
public $hasMany = [
MatchModel::class
];
}
And the entitities are defined like this, without any further code:
<?php namespace App\Entities;
use OrmExtension\Extensions\Entity;
class Venue extends Entity
{
//
}
``
I've setup a project from scratch with this composer file
"require": {
"codeigniter4/framework": "4.0.2",
"4spacesdk/ci4ormextension": "1.0.0-beta.22"
}
And this database:
CREATE TABLE `matches` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`venue_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
CREATE TABLE `matches` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`venue_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
This controller code
class Home extends BaseController
{
public function index()
{
$matchModel = new MatchModel();
/** @var Match $matches */
$matches = $matchModel->includeRelated(VenueModel::class)->find();
echo $matches->count();
}
}
No issues found.
Here is a zip of the complete project.
CI4OrmExtensionIssue3.zip
Yes, your test project works for me as well, but my own doesn't. The only difference I can see is that I also have the myth-auth package installed, which should not be an issue I think.
I did find another issue in your test project, but I will open a separate issue for it.
If you provide a copy of your project, I will take a look :)
If you provide a copy of your project, I will take a look :)
It's quite a few mb's, how do you want me to send it to you?
One observation: I do not see the Match_relations file in the writable/cache folder in my project.
You can attach a zip file in a comment here or send it to my email address.
I really appreciate your help. It worked at first, but when I started adding my controllers & views and such, it stopped working. Here is a zip, you just need to adjust the .env file I think.
CI4OrmExtensionIssue3.zip
Also, here is an export of the two tables involved:
Try updating to CI4OrmExtension to 1.0.0-beta.23.
The issue was triggered by myth/auth using Closures in a Config file. The config file were attached to model which OrmExtension tried to serialize.
I've adjusted OrmExtension to avoid caching objects and instead use the class name. :)
Thanks for the support @Martin-4Spaces, it works like a charm now.
NP! :)