To offer an alternative to what Phil said, I believe the problem is that you’re loading the class via CI’s Loader, which calls _assign_libraries. If you follow the DMZ way of not calling load->model and just do a “new Whatever()” you shouldn’t run into that problem.
Good call. I actually didn’t know that CodeIgniter calls _assign_libraries on models.
I’ll have to think about what to do. It’s actually kinda bad to use Loader::model(), since DMZ specifically says don’t do it.
I might rename _assign_libraries (like, _assign_libraries_private), then use the original method to throw an error when models get loaded manually. This will prevent DMZ models from being loaded by CI.
Or, I could just let CI load the model, but there’s no telling if that would be a problem or not.
@Mareshal
I don’t know what to tell you. It’s not DMZ — there’s no parse errors with the source for the admin.php file. It hasn’t been changed since 8/25/2009 (I can see it in the repository).
I just double-checked the ZIP, too, it’s OK there.
@Mareshal
Well, did you try to run the admin.php file through PHP lint (-l)?
Did you check to see if the file was corrupt?
Also, why are you using the CI from bitbucket? Are you sure it is an official version? The latest version of CI is 1.7.2. You might have issues with running a pre-release or dev version of CI.
I can’t help you much more. You’ve basically said “I’ve installed it, it doesn’t work.” But it does work. The example app is my main testing ground for DMZ. I run it all the time. Is it configured correctly?
I think the example app still uses short tags, since I prefer them. Maybe you need to enable short tags.
I can’t help beyond that. Feel free to update if you figure out what the problem is.
My app’s loading models using CI->load->model(), I guess that’s my bad. CI’s load->model() calls _assign_libraries() on the loaded model, which causes the fatal error.
My app’s running under Expression Engine 2.0, which sits on top of CodeIgniter. I’m guessing EE uses an early version of CI version 2; it allows addons to be packaged into a third party directory and supports include paths for libraries and models which DataMapper’s autoload() doesn’t know about. That’s why the app needed its models manually loaded through CI, DataMapper couldn’t find ‘em. I have a patch to autoload() that reads the CI include path, I’ll post it if you like.
While debugging the patch, I noticed autoload() fires each time ExpressionEngine loads ones of its modules or plugins. I’m not sure if that’s a good thing, it could cause a problem if a plugin and model share the same name.
is it worth considering letting CI load DataMapper models? I never noticed a problem with CI-loaded models under DataMapper 1.6.2 or earlier versions, and I’ve been working on this app for several months. Letting CI handle loading is less likely to trip up CI users new to DataMapper, and might save some problems in the future as CI grows. I like your idea of renaming _assign_libraries() to _assign_libraries_private(), that should allow models to autoload or let them load through CI.
@Jack Scott
Regarding the autoload method: it’s going to be called anytime a class is requested that hasn’t already been loaded, no matter where that class is called. (It’s related to the way PHP loads classes.) Due to the required naming scheme (ie: that every model has to have a unique class name across the entire app, and the file name is the same as the class), it shouldn’t ever cause an issue. (You cannot have any other classes with the same name as your DMZ models, just like you can’t have any two classes with the same name, anywhere.)
I’m not ready to start worrying about CI 2.0 yet, and I don’t have access to EE. Feel free to post it, but I’m probably not going to be worrying about it too soon.
I don’t think there is an issue with letting CI load the models, other than if CI loads a model, that model gets instantiated whether or not it is used. If you let DMZ lazily load the models, then only the models needed for that request get loaded. I wasn’t going to allow models to be loaded via CodeIgniter, even with the name change, just provide a better error, but I’ll think about it. (It’s important to realize that DMZ models aren’t truly CodeIgniter models - they don’t share any code with CI’s models, and they work very differently.)
Thanks for the above comments. I’ll continue using my workaround.
I have another situation that I’m unsure how to handle. Basically I want to create a relationship where the PK of the relationship is defined by the ids of three other models. A bit like a join table but with 3 FKs.
To put it into its real world example, I have two models, Project and Location, which have a M*M relationship, using a join table. I have another model, Document, and I want to relate this to the relationship between the Project and the Location. I can’t use a field in the join table as that would only allow for one Document to be related. I’m not sure that it’s a good idea to create another join table that relates Documents to the Project/Location join table. Maybe this is something else that I’ll have to do outside of the DMZ framework?
The updated autoload() method is included below. It uses the loader’s _ci_model_paths property to locate models. I suspect this is intended to be a private property, and may not work in future versions, but we’ll cross that bridge when we get to it.
public static function autoload($class) { // Don't attempt to autoload CI_ or MY_ prefixed classes if (in_array(substr($class, 0, 3), array('CI_', 'EE_', 'MY_'))) { return; }
// Prepare class $class = strtolower($class);
// Prepare path $CI =& get_instance(); if (isset($CI->load->_ci_model_paths) && is_array($CI->load->_ci_model_paths)) { // use CI loader's model path $paths = $CI->load->_ci_model_paths; } else { $paths = array(APPPATH); }
// Check if file exists, require_once if it does if (file_exists($file)) { require_once($file); break; } }
// if class not loaded, do a recursive search of APPPATH for the class if (! class_exists($class)) { DataMapper::recursive_require_once($class, APPPATH . 'models'); } }