I think this might be impossible, but... is there any way to extend a namespaced class in a package (Orm\Query, for example), using the same namespace? Essentially, extending and replacing the original class, similar to extending a core class aliased to global.
In this case, I'd like to add a new method to Orm\Query, and have that method be available whenever I get a resultset from the ORM. This would require the ORM to use my extended Query class, though, and I don't see a way to make that happen. Any thoughts?
A result from any ORM query is a Model or array of Models. So if you want to have additional methods available, you need to extend the Model, not the Query object.
Extending the Model is easy, just create a base model in your app:
in fuel/app/classes/model/base.php:
namespace Model; class Base extends \Orm\Model {}
And have all your models extend this class instead of \Orm\Model.
Extending the Query object is not so simple, as the Orm model calls that internally, it is not aliased like the core (so you can not use the autoloader to inject an extended class) and Fuel v1 doesn't have any dependency injection allowing you to swap classes.
You can try copying the class to ./fuel/app/classes/orm/query.php, and then use Autoloader::add_class('Orm\Query', APPPATH.'classes/orm/query.php'), after the Orm package is loaded, to make sure your file is loaded when the query class is requested, but I have never tried that.
Yeah, I shouldn't have said an ORM "resultset"... I've already got custom extensions to Orm\Model. It's definitely the Orm\Query class I want to extend.
Your solution works, but of course it would require maintaining my own copy of the Orm\Query class, which would could cause problems when updating the ORM package. I think the only way to accomplish this would be using something like runkit to add a method to Orm\Query at runtime.
Actually, now that we're near the end of 1.x, there probably won't be many more updates to the ORM package. Maybe maintaining a copy isn't such a big deal. And hopefully this type of extension can be handled more elegantly in v2!
v2 has a dependency injection container, so you can swap any class with any other, it doesn't use Aliasing (only for making classes available in a different namespace).
There's a 1.7.1. coming (backport of 1.8/develop), which has quite a few bugfixes, so you might want to wait for that, or switch your app to 1.8/develop.