As I stated in the introduction, the CodeIgniter library that I plan to build here will perform CRUD operations against a selected database table, without the need to create many complex models. It will rely partially on Simon Stenhouse’s DataMapper, which has been a great source of inspiration for writing mine, even though I enhanced some aspects of it (such as the recursive load of required files by means of directory iterators supplied by the Standard PHP Library (SPL)). That being said, it’s time to start creating the library. In its initial stage, it looks like this: The MIT License
Copyright (c) 2008 Simon Stenhouse
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class AbstractModel { protected $table = ''; protected $fields = array(); protected $validation = array(); protected $error_prefix = '<p>'; protected static $instance = NULL; protected $ci = NULL; protected $db = NULL;
// Factory method that creates a singleton model object public static function factory($model) { if (self::$instance == NULL) { $model = ucfirst($model); self::$instance = new $model; } return self::$instance; }
// Constructor public function __construct() { $this->ci = & get_instance(); $this->db = $this->ci->db; $table = strtolower(get_class($this)) . 's'; if ($this->db->table_exists($table)) { $this->table = $table; $this->fields = $this->db->field_names($this->table); } else { return; } } } As shown previously, the above “AbstractModel” class defines some simple properties that are pretty self-explanatory, such as the name of the database table that it’ll be associated with, the fields of that specific table, the validation rules that will be applied to the data before inserting and updating a record, and so forth. It’s worth paying close attention to two of these properties, called “$ci” and “$instance” respectively. The first one will store an instance of the CodeIgniter super object (required for using its database class), and the last one will be used for returning a Singleton of the “AbstractModel” class. The first method implemented above, called “factory(),” as its name implies, is used for factoring only one instance of the class. Naturally, it should be used instead of explicitly calling its constructor, since it can be chained to other methods easily. Lastly, there’s the constructor, which is responsible for grabbing an instance of the CI super object, as well for determining if the database associated with the abstract model really exists. In this specific case, I decided to use a simple convention-over-configuration rule that assumes that the name of the associated table is simply the name of the model plus an “s.” However, it’s possible to implement a more complex process for associating a model to a table by using, for instance, the CodeIgniter inflector helper. So far, so good. At this point the “AbstractModel” class still looks pretty useless, since it only implements a couple of methods so far. It’s valid to stress, though, that one of them is chainable, thus demonstrating how method chaining can be used for developing a production application. Now, it’s time to keep extending the functionality of the previous class by defining some other methods. This will be done in the following section, so click on the link below and read the next few lines.
blog comments powered by Disqus |
|
|
|
|
|
|
|