Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /**
- * @version 0.5.0
- * @author David Vega
- * @subpackage Record
- */
- /**
- * The Record (Object Relationship Mapping) class is an abstract class that
- * sets the needed codebase to be able to do database tuple manipulation
- * in an object oriented fashion, this is, loading/inserting/updating/deleting
- * tuples from the database.
- *
- * The definition of the Record is done by inheriting the abstract class and
- * implementing the abstract _archetype function.
- *
- * i.e.
- *
- * class Foo extends Record{
- * protected function ¬archetype(){
- * $this->setTable('foos')
- * ->setPrimaryKey('id','int')
- * ->setField('bar','string');
- * }
- * }
- *
- * $foo = new Foo(); //Empty object ready for assigning data
- * $foo->bar = "hello world"; //RecordFields are accessed directly as if they were member variables
- * if($foo->save()){ //If the tuple is inserted
- * $foo_reloaded = new Foo($foo->id); //the actual value(s) from the primary key(s) are updated into the object, and we use it (or them) to retrieve the data into the object
- * $foo_reloaded->bar = "Hello world!" //We put more emotion into it!
- * $foo_reloaded->save(); //The save() method tries to update with the loaded primary keys
- * }
- *
- * @subpackage Record
- */
- abstract class Record{
- /**
- * Array of RecordField objects by reference whose values will define
- * the tuple to retrieve from the database when passed to the
- * constructor.
- * @var array
- */
- private $_primary_keys = array();
- /**
- * Associative array of RecordField instances with the name of the field
- * as a key. The RecordField objets define the table represented by this
- * object.
- *
- * @var array
- */
- private $_fields = array();
- /**
- * The name of the table represented by the Record
- * @var string
- */
- private $_table = NULL;
- /**
- * The Database object by reference to be used for the queries
- * @var Database
- */
- private $_database = NULL;
- /**
- * The constructor takes the specified number of primary keys (can be compound)
- * as argument and loads a tuple from the database. If more arguments are passed
- * it will start filling for the rest of the specified columns.
- *
- * When using the Record you must extend your class and implement the _archetype()
- * function and specify the schema in it. You may do it manualy or with an
- * XML node or file.
- *
- * The object will only load if its passed the number of primary keys specified or
- * more arguments. If no database is specified it will load the default singleton
- * instance.
- *
- * @return Record The object instance.
- */
- public function __construct(){
- $this->_archetype();
- $_args = func_get_args();
- if(is_array($_args[0])){
- $_args = array_values($_args[0]);
- }
- $_numargs = count($_args);
- if($this->_database === NULL){
- $this->_database = Database::singleton();
- }
- if($_numargs >= count($this->_primary_keys)){
- $pk_arg_index = 0;
- foreach($this->_primary_keys as $field){
- $field->setValue($_args[$pk_arg_index++]);
- }
- if($this->_table !== NULL){
- $field_names = array();
- foreach($this->_fields as $field){
- array_push($field_names,$field->getName());
- }
- $conditions = array();
- foreach($this->_primary_keys as $field){
- $conditions[$field->getName()] = $field->getValue();
- }
- $conditions = sql_conditions_string($conditions);
- $data = $this->_database->getDataRow('select '.(implode(',',$field_names)).' from '.($this->_table).' where '.($conditions));
- if($data !== NULL){
- foreach($field_names as $field_name){
- $this->_fields[$field_name]->setValue($data[$field_name]);
- }
- }else{
- foreach($this->_primary_keys as $field){
- $field->setValue($field->getDefault());
- }
- }
- }
- }
- if($_numargs >= (count($this->_primary_keys)+1)){
- $field_index = 0;
- for($field_arg_index = count($this->_primary_keys);$field_arg_index < (count($_args)-1);$field_arg_index++){
- $this->_fields[$field_index]->setValue($_args[$field_arg_index]);
- $field_index++;
- }
- }
- }
- /**
- * If no arguments are given, the primary keys, fields, table and database are reset.
- * @param [array $primary_keys[, array $fields[, string $table[, Database $database]]]]
- */
- protected function setSchema(){
- $_args = func_get_args();
- $_numargs = count($_args);
- if($_numargs === 0){
- $this->_primary_keys= array();
- $this->_fields = array();
- $this->_table = NULL;
- $this->_database = Database::singleton();
- }else{
- if($_numargs >= 1){$this->setPrimaryKeys($_args[0]);}
- if($_numargs >= 2){$this->setFields ($_args[1]);}
- if($_numargs >= 3){$this->setTable ($_args[2]);}
- if($_numargs >= 4){$this->setDatabase ($_args[3]);}
- }
- }
- /**
- * Returns by reference an array of size 4 with the array of primary keys, the array of fields, the table name and the database object.
- * @return array
- */
- protected function &getSchema(){
- return array(
- $this->_primary_keys,
- $this->_fields,
- $this->_table,
- $this->_database
- );
- }
- /**
- * Tries to create the table for the schema set in the object
- * @todo Implement function that should be able to generate and execute the suitable script to create the needed tables
- */
- protected function deploySchema(){
- }
- /**
- * Abstract function where the schema is specified and instantiated.
- */
- abstract protected function ¬archetype();
- /**
- *
- * @method
- */
- public function fetch(){
- }
- //Accessors & Mutators
- /**
- * Magical accessor; allows the object schema's attributes to
- * be accessed directly.
- *
- * i.e.
- *
- * class User extends Record{...}
- *
- * $user = new User(23); //Loads the tuple from the database
- * $username = $user->username; //Gets the value loaded in the RecordField object
- *
- * @return mixed $attribute
- */
- public function __get($field_name){
- if(isset($this->_primary_keys[$field_name])){
- return $this->_primary_keys[$field_name]->getValue();
- }else if(isset($this->_fields[$field_name])){
- return $this->_fields[$field_name]->getValue();
- }else{
- die("Undefined gettable member $field_name for class ".get_class($this));
- }
- }
- /**
- * Magical setter, allows the modification of the value stored in
- * the attributes as if it was a regular object variable
- *
- * i.e.
- *
- * class User extends Record{...}
- *
- * $user = new User();
- * $user->username = "Dude"; //Dynamic setter in action
- *
- */
- public function __set($field_name,$value){
- if(isset($this->_primary_keys[$field_name])){
- $this->_primary_keys[$field_name]->setValue($value);
- }else if(isset($this->_fields[$field_name])){
- $this->_fields[$field_name]->setValue($value);
- }else{
- die("Undefined settable member $field_name for class ".get_class($this));
- }
- }
- /**
- * Returns the array of RecordField objects by reference.
- * @return array
- */
- protected function &getPrimaryKeys(){
- return $this->_primary_keys;
- }
- /**
- * Returns the specified RecordField object by reference or NULL if it doesn't exist.
- * @param string $primary_key_name
- * @return RecordField
- */
- protected function &getPrimaryKey($primary_key_name){
- return (array_key_exists($primary_key_name,$this->_primary_keys))?($this->_primary_keys[$primary_key_name]):NULL;
- }
- protected function &getFields(){
- return $this->_fields;
- }
- protected function &getField($fieldname){
- return $this->_fields[$fieldname];
- }
- protected function getTable(){
- return $this->_table;
- }
- protected function &getDatabase(){
- return $this->_database;
- }
- /**
- *
- */
- protected function setPrimaryKey(){
- $pk_field = new RecordField(func_get_args());
- $pk_field->setRecord($this);
- $this->_primary_keys[$pk_field->getName()] = $pk_field;
- }
- protected function unsetPrimaryKey($fieldname){
- if(isset($this->_primary_keys[$fieldname])){
- unset($this->_primary_keys[$fieldname]);
- return true;
- }return false;
- }
- protected function setField(){
- $field = new RecordField(func_get_args());
- $field->setRecord($this);
- $this->_fields[$field->getName()] = $field;
- }
- protected function unsetField($fieldname){
- if(isset($this->_fields[$fieldname])){
- unset($this->_fields[$fieldname]);
- return true;
- }return false;
- }
- protected function setTable($t){
- $this->_table = (string)($t);
- }
- protected function setDatabase(Database $db){
- $this->_database = &$db;
- }
- //Methods & Functions
- public function save(){
- if($this->_table === NULL){
- return false;
- }
- $is_new = true;
- foreach($this->_primary_keys as $field){
- if( !($field->getValue() === NULL) || !($field->getValue() === $field->getDefault()) ){
- $is_new = false;
- break;
- }
- }
- $fields_data = array();
- foreach($this->_fields as $field){
- $fields_data[$field->getName()] = $field->getValue();
- }
- if($is_new){
- return $this->_database->insert($this->_table,$fields_data);
- }else{
- $conditions = array();
- foreach($this->_primary_keys as $field){
- $conditions[$field->getName()] = $field->getValue();
- }
- return $this->_database->update($this->_table,$fields_data,$conditions);
- }
- }
- public function delete(){
- $conditions = array();
- foreach($this->_primary_keys as $pkf){
- $conditions[$pkf->getName()] = $pkf->getValue();
- }
- return $this->_database->delete($this->_table,$conditions);
- }
- protected function buildXML(){
- $dom_xml = new DOMDocument('1.0', 'iso-8859-1');
- $dom_xml_model = $dom_xml->createElement('model');
- $dom_xml_model->setAttribute('table',(string)$this->_table);
- if($this->_database !== Database::singleton()){
- $dom_xml_model_database = $dom_xml_model->createElement('database');
- $dom_xml_model_database->setAttribute('server', (string)$this->_database->getServer());
- $dom_xml_model_database->setAttribute('user', (string)$this->_database->getUser());
- $dom_xml_model_database->setAttribute('name', (string)$this->_database->getName());
- $dom_xml_model->appendChild($dom_xml_model_database);
- }
- $dom_xml_model_fields = $dom_xml->createElement('fields');
- $dom_xml_pk_model_fields = $dom_xml->createElement('primary');
- foreach($this->_primary_keys as $field){
- $simplexml_model_field = $field->buildXML();
- $dom_simplexml_model_field = dom_import_simplexml($simplexml_model_field);
- if(!$dom_simplexml_model_field){
- die('XML parse error.');
- }
- $dom_simplexml_model_field = $dom_xml_pk_model_fields->importNode($dom_simplexml_model_field);
- $dom_xml_pk_model_fields->appendChild($dom_simplexml_model_field);
- }
- $dom_xml_model_fields = $dom_xml->createElement('nrecordal');
- foreach($this->_fields as $field){
- $simplexml_model_field = $field->buildXML();
- $dom_simplexml_model_field = dom_import_simplexml($simplexml_model_field);
- if(!$dom_simplexml_model_field){
- die('XML parse error.');
- }
- $dom_simplexml_model_field = $dom_xml_model_fields->importNode($dom_simplexml_model_field);
- $dom_xml_model_fields->appendChild($dom_simplexml_model_field);
- }
- return simplexml_import_dom($dom_xml);
- }
- protected function parseXML(SimpleXMLElement $xml_node){
- if($xml_node->getName() === 'model'){
- }
- }
- protected function exportXML(){
- }
- protected function importXML(){
- }
- }
Add Comment
Please, Sign In to add comment