Guest User

Untitled

a guest
Jun 22nd, 2018
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.69 KB | None | 0 0
  1. <?php
  2. /**
  3. * @version 0.5.0
  4. * @author David Vega
  5. * @subpackage Record
  6. */
  7.  
  8. /**
  9. * The Record (Object Relationship Mapping) class is an abstract class that
  10. * sets the needed codebase to be able to do database tuple manipulation
  11. * in an object oriented fashion, this is, loading/inserting/updating/deleting
  12. * tuples from the database.
  13. *
  14. * The definition of the Record is done by inheriting the abstract class and
  15. * implementing the abstract _archetype function.
  16. *
  17. * i.e.
  18. *
  19. * class Foo extends Record{
  20. * protected function ¬archetype(){
  21. * $this->setTable('foos')
  22. * ->setPrimaryKey('id','int')
  23. * ->setField('bar','string');
  24. * }
  25. * }
  26. *
  27. * $foo = new Foo(); //Empty object ready for assigning data
  28. * $foo->bar = "hello world"; //RecordFields are accessed directly as if they were member variables
  29. * if($foo->save()){ //If the tuple is inserted
  30. * $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
  31. * $foo_reloaded->bar = "Hello world!" //We put more emotion into it!
  32. * $foo_reloaded->save(); //The save() method tries to update with the loaded primary keys
  33. * }
  34. *
  35. * @subpackage Record
  36. */
  37. abstract class Record{
  38. /**
  39. * Array of RecordField objects by reference whose values will define
  40. * the tuple to retrieve from the database when passed to the
  41. * constructor.
  42. * @var array
  43. */
  44. private $_primary_keys = array();
  45. /**
  46. * Associative array of RecordField instances with the name of the field
  47. * as a key. The RecordField objets define the table represented by this
  48. * object.
  49. *
  50. * @var array
  51. */
  52. private $_fields = array();
  53. /**
  54. * The name of the table represented by the Record
  55. * @var string
  56. */
  57. private $_table = NULL;
  58. /**
  59. * The Database object by reference to be used for the queries
  60. * @var Database
  61. */
  62. private $_database = NULL;
  63.  
  64. /**
  65. * The constructor takes the specified number of primary keys (can be compound)
  66. * as argument and loads a tuple from the database. If more arguments are passed
  67. * it will start filling for the rest of the specified columns.
  68. *
  69. * When using the Record you must extend your class and implement the _archetype()
  70. * function and specify the schema in it. You may do it manualy or with an
  71. * XML node or file.
  72. *
  73. * The object will only load if its passed the number of primary keys specified or
  74. * more arguments. If no database is specified it will load the default singleton
  75. * instance.
  76. *
  77. * @return Record The object instance.
  78. */
  79. public function __construct(){
  80. $this->_archetype();
  81.  
  82. $_args = func_get_args();
  83. if(is_array($_args[0])){
  84. $_args = array_values($_args[0]);
  85. }
  86. $_numargs = count($_args);
  87.  
  88. if($this->_database === NULL){
  89. $this->_database = Database::singleton();
  90. }
  91.  
  92. if($_numargs >= count($this->_primary_keys)){
  93. $pk_arg_index = 0;
  94. foreach($this->_primary_keys as $field){
  95. $field->setValue($_args[$pk_arg_index++]);
  96. }
  97.  
  98. if($this->_table !== NULL){
  99. $field_names = array();
  100. foreach($this->_fields as $field){
  101. array_push($field_names,$field->getName());
  102. }
  103.  
  104. $conditions = array();
  105. foreach($this->_primary_keys as $field){
  106. $conditions[$field->getName()] = $field->getValue();
  107. }
  108. $conditions = sql_conditions_string($conditions);
  109.  
  110. $data = $this->_database->getDataRow('select '.(implode(',',$field_names)).' from '.($this->_table).' where '.($conditions));
  111.  
  112. if($data !== NULL){
  113. foreach($field_names as $field_name){
  114. $this->_fields[$field_name]->setValue($data[$field_name]);
  115. }
  116. }else{
  117. foreach($this->_primary_keys as $field){
  118. $field->setValue($field->getDefault());
  119. }
  120. }
  121. }
  122. }
  123.  
  124. if($_numargs >= (count($this->_primary_keys)+1)){
  125.  
  126. $field_index = 0;
  127. for($field_arg_index = count($this->_primary_keys);$field_arg_index < (count($_args)-1);$field_arg_index++){
  128. $this->_fields[$field_index]->setValue($_args[$field_arg_index]);
  129. $field_index++;
  130. }
  131. }
  132. }
  133.  
  134. /**
  135. * If no arguments are given, the primary keys, fields, table and database are reset.
  136. * @param [array $primary_keys[, array $fields[, string $table[, Database $database]]]]
  137. */
  138. protected function setSchema(){
  139. $_args = func_get_args();
  140. $_numargs = count($_args);
  141.  
  142. if($_numargs === 0){
  143. $this->_primary_keys= array();
  144. $this->_fields = array();
  145. $this->_table = NULL;
  146. $this->_database = Database::singleton();
  147. }else{
  148. if($_numargs >= 1){$this->setPrimaryKeys($_args[0]);}
  149. if($_numargs >= 2){$this->setFields ($_args[1]);}
  150. if($_numargs >= 3){$this->setTable ($_args[2]);}
  151. if($_numargs >= 4){$this->setDatabase ($_args[3]);}
  152. }
  153. }
  154. /**
  155. * 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.
  156. * @return array
  157. */
  158. protected function &getSchema(){
  159. return array(
  160. $this->_primary_keys,
  161. $this->_fields,
  162. $this->_table,
  163. $this->_database
  164. );
  165. }
  166. /**
  167. * Tries to create the table for the schema set in the object
  168. * @todo Implement function that should be able to generate and execute the suitable script to create the needed tables
  169. */
  170. protected function deploySchema(){
  171.  
  172. }
  173. /**
  174. * Abstract function where the schema is specified and instantiated.
  175. */
  176. abstract protected function ¬archetype();
  177. /**
  178. *
  179. * @method
  180. */
  181. public function fetch(){
  182.  
  183. }
  184. //Accessors & Mutators
  185. /**
  186. * Magical accessor; allows the object schema's attributes to
  187. * be accessed directly.
  188. *
  189. * i.e.
  190. *
  191. * class User extends Record{...}
  192. *
  193. * $user = new User(23); //Loads the tuple from the database
  194. * $username = $user->username; //Gets the value loaded in the RecordField object
  195. *
  196. * @return mixed $attribute
  197. */
  198. public function __get($field_name){
  199. if(isset($this->_primary_keys[$field_name])){
  200. return $this->_primary_keys[$field_name]->getValue();
  201. }else if(isset($this->_fields[$field_name])){
  202. return $this->_fields[$field_name]->getValue();
  203. }else{
  204. die("Undefined gettable member $field_name for class ".get_class($this));
  205. }
  206. }
  207. /**
  208. * Magical setter, allows the modification of the value stored in
  209. * the attributes as if it was a regular object variable
  210. *
  211. * i.e.
  212. *
  213. * class User extends Record{...}
  214. *
  215. * $user = new User();
  216. * $user->username = "Dude"; //Dynamic setter in action
  217. *
  218. */
  219. public function __set($field_name,$value){
  220. if(isset($this->_primary_keys[$field_name])){
  221. $this->_primary_keys[$field_name]->setValue($value);
  222. }else if(isset($this->_fields[$field_name])){
  223. $this->_fields[$field_name]->setValue($value);
  224. }else{
  225. die("Undefined settable member $field_name for class ".get_class($this));
  226. }
  227. }
  228. /**
  229. * Returns the array of RecordField objects by reference.
  230. * @return array
  231. */
  232. protected function &getPrimaryKeys(){
  233. return $this->_primary_keys;
  234. }
  235. /**
  236. * Returns the specified RecordField object by reference or NULL if it doesn't exist.
  237. * @param string $primary_key_name
  238. * @return RecordField
  239. */
  240. protected function &getPrimaryKey($primary_key_name){
  241. return (array_key_exists($primary_key_name,$this->_primary_keys))?($this->_primary_keys[$primary_key_name]):NULL;
  242. }
  243. protected function &getFields(){
  244. return $this->_fields;
  245. }
  246. protected function &getField($fieldname){
  247. return $this->_fields[$fieldname];
  248. }
  249. protected function getTable(){
  250. return $this->_table;
  251. }
  252. protected function &getDatabase(){
  253. return $this->_database;
  254. }
  255. /**
  256. *
  257. */
  258. protected function setPrimaryKey(){
  259. $pk_field = new RecordField(func_get_args());
  260. $pk_field->setRecord($this);
  261. $this->_primary_keys[$pk_field->getName()] = $pk_field;
  262. }
  263. protected function unsetPrimaryKey($fieldname){
  264. if(isset($this->_primary_keys[$fieldname])){
  265. unset($this->_primary_keys[$fieldname]);
  266. return true;
  267. }return false;
  268. }
  269. protected function setField(){
  270. $field = new RecordField(func_get_args());
  271. $field->setRecord($this);
  272. $this->_fields[$field->getName()] = $field;
  273. }
  274. protected function unsetField($fieldname){
  275. if(isset($this->_fields[$fieldname])){
  276. unset($this->_fields[$fieldname]);
  277. return true;
  278. }return false;
  279. }
  280. protected function setTable($t){
  281. $this->_table = (string)($t);
  282. }
  283. protected function setDatabase(Database $db){
  284. $this->_database = &$db;
  285. }
  286. //Methods & Functions
  287. public function save(){
  288. if($this->_table === NULL){
  289. return false;
  290. }
  291.  
  292. $is_new = true;
  293. foreach($this->_primary_keys as $field){
  294. if( !($field->getValue() === NULL) || !($field->getValue() === $field->getDefault()) ){
  295. $is_new = false;
  296. break;
  297. }
  298. }
  299.  
  300. $fields_data = array();
  301. foreach($this->_fields as $field){
  302. $fields_data[$field->getName()] = $field->getValue();
  303. }
  304.  
  305. if($is_new){
  306. return $this->_database->insert($this->_table,$fields_data);
  307. }else{
  308. $conditions = array();
  309. foreach($this->_primary_keys as $field){
  310. $conditions[$field->getName()] = $field->getValue();
  311. }
  312. return $this->_database->update($this->_table,$fields_data,$conditions);
  313. }
  314. }
  315. public function delete(){
  316. $conditions = array();
  317. foreach($this->_primary_keys as $pkf){
  318. $conditions[$pkf->getName()] = $pkf->getValue();
  319. }
  320. return $this->_database->delete($this->_table,$conditions);
  321. }
  322. protected function buildXML(){
  323. $dom_xml = new DOMDocument('1.0', 'iso-8859-1');
  324. $dom_xml_model = $dom_xml->createElement('model');
  325.  
  326. $dom_xml_model->setAttribute('table',(string)$this->_table);
  327.  
  328. if($this->_database !== Database::singleton()){
  329. $dom_xml_model_database = $dom_xml_model->createElement('database');
  330. $dom_xml_model_database->setAttribute('server', (string)$this->_database->getServer());
  331. $dom_xml_model_database->setAttribute('user', (string)$this->_database->getUser());
  332. $dom_xml_model_database->setAttribute('name', (string)$this->_database->getName());
  333.  
  334. $dom_xml_model->appendChild($dom_xml_model_database);
  335. }
  336.  
  337. $dom_xml_model_fields = $dom_xml->createElement('fields');
  338.  
  339. $dom_xml_pk_model_fields = $dom_xml->createElement('primary');
  340. foreach($this->_primary_keys as $field){
  341. $simplexml_model_field = $field->buildXML();
  342. $dom_simplexml_model_field = dom_import_simplexml($simplexml_model_field);
  343. if(!$dom_simplexml_model_field){
  344. die('XML parse error.');
  345. }
  346. $dom_simplexml_model_field = $dom_xml_pk_model_fields->importNode($dom_simplexml_model_field);
  347. $dom_xml_pk_model_fields->appendChild($dom_simplexml_model_field);
  348. }
  349.  
  350. $dom_xml_model_fields = $dom_xml->createElement('nrecordal');
  351. foreach($this->_fields as $field){
  352. $simplexml_model_field = $field->buildXML();
  353. $dom_simplexml_model_field = dom_import_simplexml($simplexml_model_field);
  354. if(!$dom_simplexml_model_field){
  355. die('XML parse error.');
  356. }
  357. $dom_simplexml_model_field = $dom_xml_model_fields->importNode($dom_simplexml_model_field);
  358. $dom_xml_model_fields->appendChild($dom_simplexml_model_field);
  359. }
  360.  
  361. return simplexml_import_dom($dom_xml);
  362. }
  363. protected function parseXML(SimpleXMLElement $xml_node){
  364. if($xml_node->getName() === 'model'){
  365.  
  366. }
  367. }
  368. protected function exportXML(){
  369.  
  370. }
  371. protected function importXML(){
  372.  
  373. }
  374. }
Add Comment
Please, Sign In to add comment